mirror of https://github.com/aap/librw.git
Merge branch 'master' of github.com:aap/librw
This commit is contained in:
commit
0d8dc5d799
100
premake5.lua
100
premake5.lua
|
@ -1,3 +1,6 @@
|
|||
GLEWdir = "C:/Users/aap/src/glew-2.1.0"
|
||||
GLFW64dir = "C:/Users/aap/src/glfw-3.2.1.bin.WIN64"
|
||||
|
||||
workspace "librw"
|
||||
location "build"
|
||||
language "C++"
|
||||
|
@ -9,8 +12,8 @@ workspace "librw"
|
|||
"win-amd64-null", "win-amd64-gl3", "win-amd64-d3d9" }
|
||||
filter { "system:linux" }
|
||||
platforms { "linux-x86-null", "linux-x86-gl3",
|
||||
"linux-amd64-null", "linux-amd64-gl3" }
|
||||
-- TODO: ps2
|
||||
"linux-amd64-null", "linux-amd64-gl3",
|
||||
"ps2" }
|
||||
filter {}
|
||||
|
||||
filter "configurations:Debug"
|
||||
|
@ -28,8 +31,12 @@ workspace "librw"
|
|||
defines { "RW_GL3" }
|
||||
filter { "platforms:*d3d9" }
|
||||
defines { "RW_D3D9" }
|
||||
filter { "platforms:*ps2" }
|
||||
filter { "platforms:ps2" }
|
||||
defines { "RW_PS2" }
|
||||
toolset "gcc"
|
||||
gccprefix 'ee-'
|
||||
buildoptions { "-nostdlib", "-fno-common" }
|
||||
includedirs { "$(PS2SDK)/ee/include", "$(PS2SDK)/common/include" }
|
||||
|
||||
filter { "platforms:*amd64*" }
|
||||
architecture "x86_64"
|
||||
|
@ -41,8 +48,13 @@ workspace "librw"
|
|||
filter { "platforms:linux*" }
|
||||
system "linux"
|
||||
|
||||
filter { "platforms:win*gl3" }
|
||||
defines { "GLEW_STATIC" }
|
||||
includedirs { path.join(GLEWdir, "include") }
|
||||
includedirs { path.join(GLFW64dir, "include") }
|
||||
|
||||
filter "action:vs*"
|
||||
buildoptions { "/wd4996" }
|
||||
buildoptions { "/wd4996", "/wd4244" }
|
||||
|
||||
filter {}
|
||||
|
||||
|
@ -63,3 +75,83 @@ project "dumprwtree"
|
|||
includedirs { "." }
|
||||
libdirs { Libdir }
|
||||
links { "librw" }
|
||||
|
||||
function findlibs()
|
||||
filter { "platforms:linux*gl3" }
|
||||
links { "GL", "GLEW", "glfw" }
|
||||
filter { "platforms:win*gl3" }
|
||||
defines { "GLEW_STATIC" }
|
||||
filter { "platforms:win-amd64-gl3" }
|
||||
libdirs { path.join(GLEWdir, "lib/Release/x64") }
|
||||
libdirs { path.join(GLFW64dir, "lib-vc2015") }
|
||||
filter { "platforms:win-x86-gl3" }
|
||||
libdirs { path.join(GLEWdir, "lib/Release/Win32") }
|
||||
filter { "platforms:win*gl3" }
|
||||
links { "glew32s", "glfw3", "opengl32" }
|
||||
filter { "platforms:*d3d9" }
|
||||
links { "d3d9", "Xinput9_1_0" }
|
||||
filter {}
|
||||
end
|
||||
|
||||
function skeleton()
|
||||
files { "skeleton/*.cpp", "skeleton/*.h" }
|
||||
includedirs { "skeleton" }
|
||||
end
|
||||
|
||||
function skeltool(dir)
|
||||
targetdir (Bindir)
|
||||
files { path.join("tools", dir, "*.cpp"),
|
||||
path.join("tools", dir, "*.h") }
|
||||
vpaths {
|
||||
{["src"] = { path.join("tools", dir, "*") }},
|
||||
{["skeleton"] = { "skeleton/*" }},
|
||||
}
|
||||
skeleton()
|
||||
debugdir ( path.join("tools", dir) )
|
||||
includedirs { "." }
|
||||
libdirs { Libdir }
|
||||
links { "librw" }
|
||||
findlibs()
|
||||
end
|
||||
|
||||
function vucode()
|
||||
filter "files:**.dsm"
|
||||
buildcommands {
|
||||
'cpp "%{file.relpath}" | dvp-as -o "%{cfg.objdir}/%{file.basename}.o"'
|
||||
}
|
||||
buildoutputs { '%{cfg.objdir}/%{file.basename}.o' }
|
||||
filter {}
|
||||
end
|
||||
|
||||
project "clumpview"
|
||||
kind "WindowedApp"
|
||||
characterset ("MBCS")
|
||||
skeltool("clumpview")
|
||||
flags { "WinMain" }
|
||||
removeplatforms { "*null" }
|
||||
|
||||
project "ps2test"
|
||||
kind "ConsoleApp"
|
||||
targetdir (Bindir)
|
||||
vucode()
|
||||
removeplatforms { "*gl3", "*d3d9", "*null" }
|
||||
targetextension '.elf'
|
||||
includedirs { "." }
|
||||
files { "tools/ps2test/*.cpp",
|
||||
"tools/ps2test/vu/*.dsm",
|
||||
"tools/ps2test/*.h" }
|
||||
linkoptions '$(PS2SDK)/ee/startup/crt0.o'
|
||||
linkoptions { '-mno-crt0', "-T$(PS2SDK)/ee/startup/linkfile" }
|
||||
libdirs { "$(PS2SDK)/ee/lib" }
|
||||
links { "librw" }
|
||||
-- "c -lc" is a hack because we need -lc twice for some reason
|
||||
links { "c -lc", "kernel", "mf" }
|
||||
|
||||
project "ps2rastertest"
|
||||
kind "ConsoleApp"
|
||||
targetdir (Bindir)
|
||||
removeplatforms { "*gl3", "*d3d9" }
|
||||
files { "tools/ps2rastertest/*.cpp" }
|
||||
includedirs { "." }
|
||||
libdirs { Libdir }
|
||||
links { "librw" }
|
||||
|
|
3
rw.h
3
rw.h
|
@ -15,9 +15,6 @@
|
|||
#include "src/d3d/rwd3d.h"
|
||||
#include "src/d3d/rwd3d8.h"
|
||||
#include "src/d3d/rwd3d9.h"
|
||||
#ifdef RW_OPENGL
|
||||
#include <GL/glew.h>
|
||||
#endif
|
||||
#include "src/gl/rwwdgl.h"
|
||||
#include "src/gl/rwgl3.h"
|
||||
#include "src/gl/rwgl3shader.h"
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
#include <Windows.h>
|
||||
#include <rw.h>
|
||||
#include "skeleton.h"
|
||||
|
||||
using namespace sk;
|
||||
using namespace rw;
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
|
||||
GLFWwindow *window;
|
||||
int keymap[GLFW_KEY_LAST+1];
|
||||
|
||||
static void
|
||||
initkeymap(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < GLFW_KEY_LAST+1; i++)
|
||||
keymap[i] = KEY_NULL;
|
||||
keymap[GLFW_KEY_SPACE] = ' ';
|
||||
keymap[GLFW_KEY_APOSTROPHE] = '\'';
|
||||
keymap[GLFW_KEY_COMMA] = ',';
|
||||
keymap[GLFW_KEY_MINUS] = '-';
|
||||
keymap[GLFW_KEY_PERIOD] = '.';
|
||||
keymap[GLFW_KEY_SLASH] = '/';
|
||||
keymap[GLFW_KEY_0] = '0';
|
||||
keymap[GLFW_KEY_1] = '1';
|
||||
keymap[GLFW_KEY_2] = '2';
|
||||
keymap[GLFW_KEY_3] = '3';
|
||||
keymap[GLFW_KEY_4] = '4';
|
||||
keymap[GLFW_KEY_5] = '5';
|
||||
keymap[GLFW_KEY_6] = '6';
|
||||
keymap[GLFW_KEY_7] = '7';
|
||||
keymap[GLFW_KEY_8] = '8';
|
||||
keymap[GLFW_KEY_9] = '9';
|
||||
keymap[GLFW_KEY_SEMICOLON] = ';';
|
||||
keymap[GLFW_KEY_EQUAL] = '=';
|
||||
keymap[GLFW_KEY_A] = 'A';
|
||||
keymap[GLFW_KEY_B] = 'B';
|
||||
keymap[GLFW_KEY_C] = 'C';
|
||||
keymap[GLFW_KEY_D] = 'D';
|
||||
keymap[GLFW_KEY_E] = 'E';
|
||||
keymap[GLFW_KEY_F] = 'F';
|
||||
keymap[GLFW_KEY_G] = 'G';
|
||||
keymap[GLFW_KEY_H] = 'H';
|
||||
keymap[GLFW_KEY_I] = 'I';
|
||||
keymap[GLFW_KEY_J] = 'J';
|
||||
keymap[GLFW_KEY_K] = 'K';
|
||||
keymap[GLFW_KEY_L] = 'L';
|
||||
keymap[GLFW_KEY_M] = 'M';
|
||||
keymap[GLFW_KEY_N] = 'N';
|
||||
keymap[GLFW_KEY_O] = 'O';
|
||||
keymap[GLFW_KEY_P] = 'P';
|
||||
keymap[GLFW_KEY_Q] = 'Q';
|
||||
keymap[GLFW_KEY_R] = 'R';
|
||||
keymap[GLFW_KEY_S] = 'S';
|
||||
keymap[GLFW_KEY_T] = 'T';
|
||||
keymap[GLFW_KEY_U] = 'U';
|
||||
keymap[GLFW_KEY_V] = 'V';
|
||||
keymap[GLFW_KEY_W] = 'W';
|
||||
keymap[GLFW_KEY_X] = 'X';
|
||||
keymap[GLFW_KEY_Y] = 'Y';
|
||||
keymap[GLFW_KEY_Z] = 'Z';
|
||||
keymap[GLFW_KEY_LEFT_BRACKET] = '[';
|
||||
keymap[GLFW_KEY_BACKSLASH] = '\\';
|
||||
keymap[GLFW_KEY_RIGHT_BRACKET] = ']';
|
||||
keymap[GLFW_KEY_GRAVE_ACCENT] = '`';
|
||||
keymap[GLFW_KEY_ESCAPE] = KEY_ESC;
|
||||
keymap[GLFW_KEY_ENTER] = KEY_ENTER;
|
||||
keymap[GLFW_KEY_TAB] = KEY_TAB;
|
||||
keymap[GLFW_KEY_BACKSPACE] = KEY_BACKSP;
|
||||
keymap[GLFW_KEY_INSERT] = KEY_INS;
|
||||
keymap[GLFW_KEY_DELETE] = KEY_DEL;
|
||||
keymap[GLFW_KEY_RIGHT] = KEY_RIGHT;
|
||||
keymap[GLFW_KEY_LEFT] = KEY_LEFT;
|
||||
keymap[GLFW_KEY_DOWN] = KEY_DOWN;
|
||||
keymap[GLFW_KEY_UP] = KEY_UP;
|
||||
keymap[GLFW_KEY_PAGE_UP] = KEY_PGUP;
|
||||
keymap[GLFW_KEY_PAGE_DOWN] = KEY_PGDN;
|
||||
keymap[GLFW_KEY_HOME] = KEY_HOME;
|
||||
keymap[GLFW_KEY_END] = KEY_END;
|
||||
keymap[GLFW_KEY_CAPS_LOCK] = KEY_CAPSLK;
|
||||
keymap[GLFW_KEY_SCROLL_LOCK] = KEY_NULL;
|
||||
keymap[GLFW_KEY_NUM_LOCK] = KEY_NULL;
|
||||
keymap[GLFW_KEY_PRINT_SCREEN] = KEY_NULL;
|
||||
keymap[GLFW_KEY_PAUSE] = KEY_NULL;
|
||||
|
||||
keymap[GLFW_KEY_F1] = KEY_F1;
|
||||
keymap[GLFW_KEY_F2] = KEY_F2;
|
||||
keymap[GLFW_KEY_F3] = KEY_F3;
|
||||
keymap[GLFW_KEY_F4] = KEY_F4;
|
||||
keymap[GLFW_KEY_F5] = KEY_F5;
|
||||
keymap[GLFW_KEY_F6] = KEY_F6;
|
||||
keymap[GLFW_KEY_F7] = KEY_F7;
|
||||
keymap[GLFW_KEY_F8] = KEY_F8;
|
||||
keymap[GLFW_KEY_F9] = KEY_F9;
|
||||
keymap[GLFW_KEY_F10] = KEY_F10;
|
||||
keymap[GLFW_KEY_F11] = KEY_F11;
|
||||
keymap[GLFW_KEY_F12] = KEY_F12;
|
||||
keymap[GLFW_KEY_F13] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F14] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F15] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F16] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F17] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F18] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F19] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F20] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F21] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F22] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F23] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F24] = KEY_NULL;
|
||||
keymap[GLFW_KEY_F25] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_0] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_1] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_2] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_3] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_4] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_5] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_6] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_7] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_8] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_9] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_DECIMAL] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_DIVIDE] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_MULTIPLY] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_SUBTRACT] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_ADD] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_ENTER] = KEY_NULL;
|
||||
keymap[GLFW_KEY_KP_EQUAL] = KEY_NULL;
|
||||
keymap[GLFW_KEY_LEFT_SHIFT] = KEY_LSHIFT;
|
||||
keymap[GLFW_KEY_LEFT_CONTROL] = KEY_LCTRL;
|
||||
keymap[GLFW_KEY_LEFT_ALT] = KEY_LALT;
|
||||
keymap[GLFW_KEY_LEFT_SUPER] = KEY_NULL;
|
||||
keymap[GLFW_KEY_RIGHT_SHIFT] = KEY_RSHIFT;
|
||||
keymap[GLFW_KEY_RIGHT_CONTROL] = KEY_RCTRL;
|
||||
keymap[GLFW_KEY_RIGHT_ALT] = KEY_RALT;
|
||||
keymap[GLFW_KEY_RIGHT_SUPER] = KEY_NULL;
|
||||
keymap[GLFW_KEY_MENU] = KEY_NULL;
|
||||
}
|
||||
|
||||
static void KeyUp(int key) { EventHandler(KEYUP, &key); }
|
||||
static void KeyDown(int key) { EventHandler(KEYDOWN, &key); }
|
||||
|
||||
static void
|
||||
keypress(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if(key >= 0 && key <= GLFW_KEY_LAST){
|
||||
if(action == GLFW_RELEASE) KeyUp(keymap[key]);
|
||||
else if(action == GLFW_PRESS) KeyDown(keymap[key]);
|
||||
else if(action == GLFW_REPEAT) KeyDown(keymap[key]);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
EventHandler(INITIALIZE, nil);
|
||||
|
||||
engineStartParams.width = sk::globals.width;
|
||||
engineStartParams.height = sk::globals.height;
|
||||
engineStartParams.windowtitle = sk::globals.windowtitle;
|
||||
engineStartParams.window = &window;
|
||||
|
||||
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
|
||||
return 0;
|
||||
|
||||
initkeymap();
|
||||
glfwSetKeyCallback(window, keypress);
|
||||
|
||||
float lastTime = glfwGetTime()*1000;
|
||||
while(!sk::globals.quit && !glfwWindowShouldClose(window)){
|
||||
float currTime = glfwGetTime()*1000;
|
||||
float timeDelta = (currTime - lastTime)*0.001f;
|
||||
glfwPollEvents();
|
||||
|
||||
EventHandler(IDLE, &timeDelta);
|
||||
|
||||
lastTime = currTime;
|
||||
}
|
||||
|
||||
EventHandler(RWTERMINATE, nil);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,57 @@
|
|||
#include <rw.h>
|
||||
#include "skeleton.h"
|
||||
|
||||
namespace sk {
|
||||
|
||||
Globals globals;
|
||||
|
||||
bool
|
||||
InitRW(void)
|
||||
{
|
||||
if(!rw::Engine::init())
|
||||
return false;
|
||||
if(AppEventHandler(sk::PLUGINATTACH, nil) == EVENTERROR)
|
||||
return false;
|
||||
if(!rw::Engine::open())
|
||||
return false;
|
||||
if(!rw::Engine::start(&engineStartParams))
|
||||
return false;
|
||||
rw::engine->loadTextures = 1;
|
||||
|
||||
rw::TexDictionary::setCurrent(rw::TexDictionary::create());
|
||||
rw::Image::setSearchPath(".");
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TerminateRW(void)
|
||||
{
|
||||
// TODO: delete all tex dicts
|
||||
rw::Engine::stop();
|
||||
rw::Engine::close();
|
||||
rw::Engine::term();
|
||||
}
|
||||
|
||||
EventStatus
|
||||
EventHandler(Event e, void *param)
|
||||
{
|
||||
EventStatus s;
|
||||
s = AppEventHandler(e, param);
|
||||
if(e == QUIT){
|
||||
globals.quit = 1;
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
if(s == EVENTNOTPROCESSED)
|
||||
switch(e){
|
||||
case RWINITIALIZE:
|
||||
return InitRW() ? EVENTPROCESSED : EVENTERROR;
|
||||
case RWTERMINATE:
|
||||
TerminateRW();
|
||||
return EVENTPROCESSED;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
extern rw::EngineStartParams engineStartParams;
|
||||
|
||||
namespace sk {
|
||||
|
||||
using namespace rw;
|
||||
|
||||
// same as RW skeleton
|
||||
enum Key
|
||||
{
|
||||
// ascii...
|
||||
|
||||
KEY_ESC = 128,
|
||||
|
||||
KEY_F1 = 129,
|
||||
KEY_F2 = 130,
|
||||
KEY_F3 = 131,
|
||||
KEY_F4 = 132,
|
||||
KEY_F5 = 133,
|
||||
KEY_F6 = 134,
|
||||
KEY_F7 = 135,
|
||||
KEY_F8 = 136,
|
||||
KEY_F9 = 137,
|
||||
KEY_F10 = 138,
|
||||
KEY_F11 = 139,
|
||||
KEY_F12 = 140,
|
||||
|
||||
KEY_INS = 141,
|
||||
KEY_DEL = 142,
|
||||
KEY_HOME = 143,
|
||||
KEY_END = 144,
|
||||
KEY_PGUP = 145,
|
||||
KEY_PGDN = 146,
|
||||
|
||||
KEY_UP = 147,
|
||||
KEY_DOWN = 148,
|
||||
KEY_LEFT = 149,
|
||||
KEY_RIGHT = 150,
|
||||
|
||||
// some stuff ommitted
|
||||
|
||||
KEY_BACKSP = 168,
|
||||
KEY_TAB = 169,
|
||||
KEY_CAPSLK = 170,
|
||||
KEY_ENTER = 171,
|
||||
KEY_LSHIFT = 172,
|
||||
KEY_RSHIFT = 173,
|
||||
KEY_LCTRL = 174,
|
||||
KEY_RCTRL = 175,
|
||||
KEY_LALT = 176,
|
||||
KEY_RALT = 177,
|
||||
|
||||
KEY_NULL, // unused
|
||||
KEY_NUMKEYS,
|
||||
};
|
||||
|
||||
enum EventStatus
|
||||
{
|
||||
EVENTERROR,
|
||||
EVENTPROCESSED,
|
||||
EVENTNOTPROCESSED
|
||||
};
|
||||
|
||||
enum Event
|
||||
{
|
||||
INITIALIZE,
|
||||
RWINITIALIZE,
|
||||
RWTERMINATE,
|
||||
SELECTDEVICE,
|
||||
PLUGINATTACH,
|
||||
KEYDOWN,
|
||||
KEYUP,
|
||||
IDLE,
|
||||
QUIT
|
||||
};
|
||||
|
||||
struct Globals
|
||||
{
|
||||
const char *windowtitle;
|
||||
int32 width;
|
||||
int32 height;
|
||||
bool32 quit;
|
||||
};
|
||||
extern Globals globals;
|
||||
|
||||
bool InitRW(void);
|
||||
void TerminateRW(void);
|
||||
EventStatus EventHandler(Event e, void *param);
|
||||
|
||||
}
|
||||
|
||||
sk::EventStatus AppEventHandler(sk::Event e, void *param);
|
|
@ -0,0 +1,217 @@
|
|||
#include <Windows.h>
|
||||
#include <rw.h>
|
||||
#include "skeleton.h"
|
||||
|
||||
using namespace sk;
|
||||
using namespace rw;
|
||||
|
||||
#ifdef RW_D3D9
|
||||
|
||||
static int keymap[256];
|
||||
static void
|
||||
initkeymap(void)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 256; i++)
|
||||
keymap[i] = KEY_NULL;
|
||||
keymap[VK_SPACE] = ' ';
|
||||
keymap[VK_OEM_7] = '\'';
|
||||
keymap[VK_OEM_COMMA] = ',';
|
||||
keymap[VK_OEM_MINUS] = '-';
|
||||
keymap[VK_OEM_PERIOD] = '.';
|
||||
keymap[VK_OEM_2] = '/';
|
||||
for(i = '0'; i <= '9'; i++)
|
||||
keymap[i] = i;
|
||||
keymap[VK_OEM_1] = ';';
|
||||
keymap[VK_OEM_NEC_EQUAL] = '=';
|
||||
for(i = 'A'; i <= 'Z'; i++)
|
||||
keymap[i] = i;
|
||||
keymap[VK_OEM_4] = '[';
|
||||
keymap[VK_OEM_5] = '\\';
|
||||
keymap[VK_OEM_6] = ']';
|
||||
keymap[VK_OEM_3] = '`';
|
||||
keymap[VK_ESCAPE] = KEY_ESC;
|
||||
keymap[VK_RETURN] = KEY_ENTER;
|
||||
keymap[VK_TAB] = KEY_TAB;
|
||||
keymap[VK_BACK] = KEY_BACKSP;
|
||||
keymap[VK_INSERT] = KEY_INS;
|
||||
keymap[VK_DELETE] = KEY_DEL;
|
||||
keymap[VK_RIGHT] = KEY_RIGHT;
|
||||
keymap[VK_LEFT] = KEY_LEFT;
|
||||
keymap[VK_DOWN] = KEY_DOWN;
|
||||
keymap[VK_UP] = KEY_UP;
|
||||
keymap[VK_PRIOR] = KEY_PGUP;
|
||||
keymap[VK_NEXT] = KEY_PGDN;
|
||||
keymap[VK_HOME] = KEY_HOME;
|
||||
keymap[VK_END] = KEY_END;
|
||||
keymap[VK_MODECHANGE] = KEY_CAPSLK;
|
||||
for(i = VK_F1; i <= VK_F24; i++)
|
||||
keymap[i] = i-VK_F1+KEY_F1;
|
||||
keymap[VK_LSHIFT] = KEY_LSHIFT;
|
||||
keymap[VK_LCONTROL] = KEY_LCTRL;
|
||||
keymap[VK_LMENU] = KEY_LALT;
|
||||
keymap[VK_RSHIFT] = KEY_RSHIFT;
|
||||
keymap[VK_RCONTROL] = KEY_RCTRL;
|
||||
keymap[VK_RMENU] = KEY_RALT;
|
||||
}
|
||||
bool running;
|
||||
|
||||
static void KeyUp(int key) { EventHandler(KEYUP, &key); }
|
||||
static void KeyDown(int key) { EventHandler(KEYDOWN, &key); }
|
||||
|
||||
LRESULT CALLBACK
|
||||
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg){
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
if(wParam == VK_MENU){
|
||||
if(GetKeyState(VK_LMENU) & 0x8000) KeyDown(keymap[VK_LMENU]);
|
||||
if(GetKeyState(VK_RMENU) & 0x8000) KeyDown(keymap[VK_RMENU]);
|
||||
}else if(wParam == VK_CONTROL){
|
||||
if(GetKeyState(VK_LCONTROL) & 0x8000) KeyDown(keymap[VK_LCONTROL]);
|
||||
if(GetKeyState(VK_RCONTROL) & 0x8000) KeyDown(keymap[VK_RCONTROL]);
|
||||
}else if(wParam == VK_SHIFT){
|
||||
if(GetKeyState(VK_LSHIFT) & 0x8000) KeyDown(keymap[VK_LSHIFT]);
|
||||
if(GetKeyState(VK_RSHIFT) & 0x8000) KeyDown(keymap[VK_RSHIFT]);
|
||||
}else
|
||||
KeyDown(keymap[wParam]);
|
||||
break;
|
||||
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
if(wParam == VK_MENU){
|
||||
if((GetKeyState(VK_LMENU) & 0x8000) == 0) KeyUp(keymap[VK_LMENU]);
|
||||
if((GetKeyState(VK_RMENU) & 0x8000) == 0) KeyUp(keymap[VK_RMENU]);
|
||||
}else if(wParam == VK_CONTROL){
|
||||
if((GetKeyState(VK_LCONTROL) & 0x8000) == 0) KeyUp(keymap[VK_LCONTROL]);
|
||||
if((GetKeyState(VK_RCONTROL) & 0x8000) == 0) KeyUp(keymap[VK_RCONTROL]);
|
||||
}else if(wParam == VK_SHIFT){
|
||||
if((GetKeyState(VK_LSHIFT) & 0x8000) == 0) KeyUp(keymap[VK_LSHIFT]);
|
||||
if((GetKeyState(VK_RSHIFT) & 0x8000) == 0) KeyUp(keymap[VK_RSHIFT]);
|
||||
}else
|
||||
KeyUp(keymap[wParam]);
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hwnd);
|
||||
break;
|
||||
|
||||
case WM_QUIT:
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
HWND
|
||||
MakeWindow(HINSTANCE instance, int width, int height, const char *title)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = instance;
|
||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
|
||||
wc.lpszMenuName = 0;
|
||||
wc.lpszClassName = "librwD3D9";
|
||||
if(!RegisterClass(&wc)){
|
||||
MessageBox(0, "RegisterClass() - FAILED", 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HWND win;
|
||||
win = CreateWindow("librwD3D9", title,
|
||||
WS_BORDER | WS_CAPTION | WS_SYSMENU |
|
||||
WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
|
||||
0, 0, width, height, 0, 0, instance, 0);
|
||||
if(!win){
|
||||
MessageBox(0, "CreateWindow() - FAILED", 0, 0);
|
||||
return 0;
|
||||
}
|
||||
ShowWindow(win, SW_SHOW);
|
||||
UpdateWindow(win);
|
||||
return win;
|
||||
}
|
||||
|
||||
void
|
||||
pollEvents(void)
|
||||
{
|
||||
MSG msg;
|
||||
while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
|
||||
if(msg.message == WM_QUIT){
|
||||
running = false;
|
||||
break;
|
||||
}else{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE instance, HINSTANCE,
|
||||
PSTR cmdLine, int showCmd)
|
||||
{
|
||||
AllocConsole();
|
||||
freopen("CONIN$", "r", stdin);
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
|
||||
EventHandler(INITIALIZE, nil);
|
||||
|
||||
HWND win = MakeWindow(instance,
|
||||
sk::globals.width, sk::globals.height,
|
||||
sk::globals.windowtitle);
|
||||
if(win == 0){
|
||||
MessageBox(0, "MakeWindow() - FAILED", 0, 0);
|
||||
return 0;
|
||||
}
|
||||
engineStartParams.window = win;
|
||||
initkeymap();
|
||||
|
||||
if(EventHandler(RWINITIALIZE, nil) == EVENTERROR)
|
||||
return 0;
|
||||
|
||||
float lastTime = (float)GetTickCount();
|
||||
running = true;
|
||||
while(pollEvents(), !globals.quit){
|
||||
float currTime = (float)GetTickCount();
|
||||
float timeDelta = (currTime - lastTime)*0.001f;
|
||||
|
||||
EventHandler(IDLE, &timeDelta);
|
||||
|
||||
lastTime = currTime;
|
||||
}
|
||||
|
||||
EventHandler(RWTERMINATE, nil);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RW_OPENGL
|
||||
int main(int argc, char *argv[]);
|
||||
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE instance, HINSTANCE,
|
||||
PSTR cmdLine, int showCmd)
|
||||
{
|
||||
char *argv[1] = {
|
||||
"clumpview",
|
||||
};
|
||||
AllocConsole();
|
||||
freopen("CONIN$", "r", stdin);
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
|
||||
return main(1, argv);
|
||||
}
|
||||
#endif
|
|
@ -261,6 +261,7 @@ Matrix::translate(V3d *translation, CombineOp op)
|
|||
Matrix tmp;
|
||||
Matrix trans = identMat;
|
||||
trans.pos = *translation;
|
||||
trans.flags &= ~IDENTITY;
|
||||
switch(op){
|
||||
case COMBINEREPLACE:
|
||||
*this = trans;
|
||||
|
@ -301,6 +302,26 @@ Matrix::scale(V3d *scale, CombineOp op)
|
|||
return this;
|
||||
}
|
||||
|
||||
Matrix*
|
||||
Matrix::transform(Matrix *mat, CombineOp op)
|
||||
{
|
||||
Matrix tmp;
|
||||
switch(op){
|
||||
case COMBINEREPLACE:
|
||||
*this = *mat;
|
||||
break;
|
||||
case COMBINEPRECONCAT:
|
||||
mult(&tmp, mat, this);
|
||||
*this = tmp;
|
||||
break;
|
||||
case COMBINEPOSTCONCAT:
|
||||
mult(&tmp, this, mat);
|
||||
*this = tmp;
|
||||
break;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
Matrix::lookAt(const V3d &dir, const V3d &up)
|
||||
{
|
||||
|
@ -457,28 +478,12 @@ Matrix::orthogonalError(void)
|
|||
float32
|
||||
Matrix::identityError(void)
|
||||
{
|
||||
V3d r { right.x-1.0f, right.y, right.z };
|
||||
V3d u { up.x, up.y-1.0f, up.z };
|
||||
V3d a { at.x, at.y, at.z-1.0f };
|
||||
V3d r = { right.x-1.0f, right.y, right.z };
|
||||
V3d u = { up.x, up.y-1.0f, up.z };
|
||||
V3d a = { at.x, at.y, at.z-1.0f };
|
||||
return dot(r,r) + dot(u,u) + dot(a,a) + dot(pos,pos);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
bool32
|
||||
Matrix::isIdentity(void)
|
||||
{
|
||||
return matrixIsIdentity((float32*)this);
|
||||
}
|
||||
|
||||
void
|
||||
Matrix::transpose(Matrix *m1, Matrix *m2)
|
||||
{
|
||||
matrixTranspose((float32*)m1, (float32*)m2);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define PSEP_C '/'
|
||||
#define PSEP_S "/"
|
||||
#ifndef _WIN32
|
||||
|
|
|
@ -10,3 +10,11 @@ ECODE(ERR_VERSION,
|
|||
"Unsupported version %X")
|
||||
ECODE(ERR_PLATFORM,
|
||||
"Unsupported platform %d")
|
||||
ECODE(ERR_ENGINEINIT,
|
||||
"Engine could not be initialized")
|
||||
ECODE(ERR_ENGINEOPEN,
|
||||
"Engine could not be opened")
|
||||
ECODE(ERR_ENGINESTART,
|
||||
"Engine could not be started")
|
||||
ECODE(ERR_INVRASTER,
|
||||
"Invalid raster format")
|
||||
|
|
|
@ -12,18 +12,20 @@
|
|||
|
||||
namespace rw {
|
||||
|
||||
PluginList Camera::s_plglist = { sizeof(Camera), sizeof(Camera), nil, nil };
|
||||
|
||||
void
|
||||
defaultBeginUpdateCB(Camera *cam)
|
||||
{
|
||||
engine->currentCamera = cam;
|
||||
Frame::syncDirty();
|
||||
engine->beginUpdate(cam);
|
||||
engine->device.beginUpdate(cam);
|
||||
}
|
||||
|
||||
void
|
||||
defaultEndUpdateCB(Camera *cam)
|
||||
{
|
||||
engine->endUpdate(cam);
|
||||
engine->device.endUpdate(cam);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -182,7 +184,21 @@ cameraSync(ObjectWithFrame *obj)
|
|||
* and to clip space are handled by separate matrices there.
|
||||
* On these platforms the two matrices are built in the platform's
|
||||
* beginUpdate function.
|
||||
* On the PS2 the 1/2 translation/shear is removed again on the VU1.
|
||||
* On the PS2 the z- and w-rows are the same and the
|
||||
* 1/2 translation/shear is removed again on the VU1 by
|
||||
* subtracting the w-row/2 from the x- and y-rows.
|
||||
*
|
||||
* perspective:
|
||||
* 1/2w 0 ox/2w -ox/2w
|
||||
* 0 -1/2h -oy/2h oy/2h
|
||||
* 0 0 1 0
|
||||
* 0 0 1 0
|
||||
*
|
||||
* parallel:
|
||||
* 1/2w 0 ox/2w -ox/2w
|
||||
* 0 -1/2h -oy/2h oy/2h
|
||||
* 0 0 1 0
|
||||
* 0 0 0 1
|
||||
*
|
||||
* RW builds this matrix directly without using explicit
|
||||
* inversion and matrix multiplication.
|
||||
|
@ -191,8 +207,8 @@ cameraSync(ObjectWithFrame *obj)
|
|||
Camera *cam = (Camera*)obj;
|
||||
Matrix inv, proj;
|
||||
Matrix::invertOrthonormal(&inv, cam->getFrame()->getLTM());
|
||||
float32 xscl = 2.0f/cam->viewWindow.x;
|
||||
float32 yscl = 2.0f/cam->viewWindow.y;
|
||||
float32 xscl = 1.0f/(2.0f*cam->viewWindow.x);
|
||||
float32 yscl = 1.0f/(2.0f*cam->viewWindow.y);
|
||||
|
||||
proj.flags = 0;
|
||||
proj.right.x = xscl;
|
||||
|
@ -315,7 +331,14 @@ Camera::destroy(void)
|
|||
void
|
||||
Camera::clear(RGBA *col, uint32 mode)
|
||||
{
|
||||
engine->clearCamera(this, col, mode);
|
||||
engine->device.clearCamera(this, col, mode);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::showRaster(void)
|
||||
{
|
||||
// TODO: camera raster
|
||||
engine->device.showRaster(nil);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -323,8 +346,8 @@ calczShiftScale(Camera *cam)
|
|||
{
|
||||
float32 n = cam->nearPlane;
|
||||
float32 f = cam->farPlane;
|
||||
float32 N = engine->zNear;
|
||||
float32 F = engine->zFar;
|
||||
float32 N = engine->device.zNear;
|
||||
float32 F = engine->device.zFar;
|
||||
// RW does this
|
||||
N += (F - N)/10000.0f;
|
||||
F -= (F - N)/10000.0f;
|
||||
|
@ -342,6 +365,8 @@ Camera::setNearPlane(float32 near)
|
|||
{
|
||||
this->nearPlane = near;
|
||||
calczShiftScale(this);
|
||||
if(this->getFrame())
|
||||
this->getFrame()->updateObjects();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -349,6 +374,32 @@ Camera::setFarPlane(float32 far)
|
|||
{
|
||||
this->farPlane = far;
|
||||
calczShiftScale(this);
|
||||
if(this->getFrame())
|
||||
this->getFrame()->updateObjects();
|
||||
}
|
||||
|
||||
void
|
||||
Camera::setViewWindow(const V2d *window)
|
||||
{
|
||||
this->viewWindow = *window;
|
||||
if(this->getFrame())
|
||||
this->getFrame()->updateObjects();
|
||||
}
|
||||
|
||||
void
|
||||
Camera::setViewOffset(const V2d *offset)
|
||||
{
|
||||
this->viewOffset = *offset;
|
||||
if(this->getFrame())
|
||||
this->getFrame()->updateObjects();
|
||||
}
|
||||
|
||||
void
|
||||
Camera::setProjection(int32 proj)
|
||||
{
|
||||
this->projection = proj;
|
||||
if(this->getFrame())
|
||||
this->getFrame()->updateObjects();
|
||||
}
|
||||
|
||||
int32
|
||||
|
@ -424,10 +475,12 @@ Camera::streamGetSize(void)
|
|||
void
|
||||
Camera::setFOV(float32 fov, float32 ratio)
|
||||
{
|
||||
V2d v;
|
||||
float32 a = tan(fov*3.14159f/360.0f);
|
||||
this->viewWindow.x = a;
|
||||
this->viewWindow.y = a/ratio;
|
||||
this->viewOffset.set(0.0f, 0.0f);
|
||||
v.set(a, a/ratio);
|
||||
this->setViewWindow(&v);
|
||||
v.set(0.0f, 0.0f);
|
||||
this->setViewOffset(&v);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
|
||||
namespace rw {
|
||||
|
||||
PluginList Clump::s_plglist = { sizeof(Clump), sizeof(Clump), nil, nil };
|
||||
PluginList Atomic::s_plglist = { sizeof(Atomic), sizeof(Atomic), nil, nil };
|
||||
|
||||
//
|
||||
// Clump
|
||||
//
|
||||
|
@ -523,7 +526,7 @@ Atomic::getPipeline(void)
|
|||
{
|
||||
return this->pipeline ?
|
||||
this->pipeline :
|
||||
driver[platform]->defaultPipeline;
|
||||
engine->driver[platform]->defaultPipeline;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -15,9 +15,7 @@ namespace d3d {
|
|||
|
||||
bool32 isP8supported = 1;
|
||||
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DDevice9 *device = nil;
|
||||
#else
|
||||
#ifndef RW_D3D9
|
||||
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
||||
((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \
|
||||
((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 ))
|
||||
|
@ -186,7 +184,7 @@ createIndexBuffer(uint32 length)
|
|||
{
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DIndexBuffer9 *ibuf;
|
||||
device->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0);
|
||||
d3ddevice->CreateIndexBuffer(length, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ibuf, 0);
|
||||
return ibuf;
|
||||
#else
|
||||
return new uint8[length];
|
||||
|
@ -227,7 +225,7 @@ createVertexBuffer(uint32 length, uint32 fvf, int32 pool)
|
|||
{
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DVertexBuffer9 *vbuf;
|
||||
device->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, fvf, (D3DPOOL)pool, &vbuf, 0);
|
||||
d3ddevice->CreateVertexBuffer(length, D3DUSAGE_WRITEONLY, fvf, (D3DPOOL)pool, &vbuf, 0);
|
||||
return vbuf;
|
||||
#else
|
||||
(void)fvf;
|
||||
|
@ -270,7 +268,7 @@ createTexture(int32 width, int32 height, int32 numlevels, uint32 format)
|
|||
{
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DTexture9 *tex;
|
||||
device->CreateTexture(width, height, numlevels, 0,
|
||||
d3ddevice->CreateTexture(width, height, numlevels, 0,
|
||||
(D3DFORMAT)format, D3DPOOL_MANAGED, &tex, nil);
|
||||
return tex;
|
||||
#else
|
||||
|
|
|
@ -23,15 +23,15 @@ using namespace d3d;
|
|||
void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
driver[PLATFORM_D3D8]->defaultPipeline = makeDefaultPipeline();
|
||||
engine->driver[PLATFORM_D3D8]->defaultPipeline = makeDefaultPipeline();
|
||||
|
||||
driver[PLATFORM_D3D8]->rasterNativeOffset = nativeRasterOffset;
|
||||
driver[PLATFORM_D3D8]->rasterCreate = rasterCreate;
|
||||
driver[PLATFORM_D3D8]->rasterLock = rasterLock;
|
||||
driver[PLATFORM_D3D8]->rasterUnlock = rasterUnlock;
|
||||
driver[PLATFORM_D3D8]->rasterNumLevels = rasterNumLevels;
|
||||
driver[PLATFORM_D3D8]->rasterFromImage = rasterFromImage;
|
||||
driver[PLATFORM_D3D8]->rasterToImage = rasterToImage;
|
||||
engine->driver[PLATFORM_D3D8]->rasterNativeOffset = nativeRasterOffset;
|
||||
engine->driver[PLATFORM_D3D8]->rasterCreate = rasterCreate;
|
||||
engine->driver[PLATFORM_D3D8]->rasterLock = rasterLock;
|
||||
engine->driver[PLATFORM_D3D8]->rasterUnlock = rasterUnlock;
|
||||
engine->driver[PLATFORM_D3D8]->rasterNumLevels = rasterNumLevels;
|
||||
engine->driver[PLATFORM_D3D8]->rasterFromImage = rasterFromImage;
|
||||
engine->driver[PLATFORM_D3D8]->rasterToImage = rasterToImage;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
|||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
@ -359,26 +359,26 @@ defaultInstanceCB(Geometry *geo, InstanceData *inst)
|
|||
|
||||
uint8 *dst = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
|
||||
instV3d(VERT_FLOAT3, dst,
|
||||
&geo->morphTargets[0].vertices[3*inst->minVert],
|
||||
&geo->morphTargets[0].vertices[inst->minVert],
|
||||
inst->numVertices, inst->stride);
|
||||
dst += 12;
|
||||
|
||||
if(geo->flags & Geometry::NORMALS){
|
||||
instV3d(VERT_FLOAT3, dst,
|
||||
&geo->morphTargets[0].normals[3*inst->minVert],
|
||||
&geo->morphTargets[0].normals[inst->minVert],
|
||||
inst->numVertices, inst->stride);
|
||||
dst += 12;
|
||||
}
|
||||
|
||||
inst->vertexAlpha = 0;
|
||||
if(geo->flags & Geometry::PRELIT){
|
||||
inst->vertexAlpha = instColor(VERT_ARGB, dst, &geo->colors[4*inst->minVert],
|
||||
inst->vertexAlpha = instColor(VERT_ARGB, dst, &geo->colors[inst->minVert],
|
||||
inst->numVertices, inst->stride);
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
for(int32 i = 0; i < geo->numTexCoordSets; i++){
|
||||
instTexCoords(VERT_FLOAT2, dst, &geo->texCoords[i][2*inst->minVert],
|
||||
instTexCoords(VERT_FLOAT2, dst, &geo->texCoords[i][inst->minVert],
|
||||
inst->numVertices, inst->stride);
|
||||
dst += 8;
|
||||
}
|
||||
|
@ -390,26 +390,26 @@ defaultUninstanceCB(Geometry *geo, InstanceData *inst)
|
|||
{
|
||||
uint8 *src = lockVertices(inst->vertexBuffer, 0, 0, D3DLOCK_NOSYSLOCK);
|
||||
uninstV3d(VERT_FLOAT3,
|
||||
&geo->morphTargets[0].vertices[3*inst->minVert],
|
||||
&geo->morphTargets[0].vertices[inst->minVert],
|
||||
src, inst->numVertices, inst->stride);
|
||||
src += 12;
|
||||
|
||||
if(geo->flags & Geometry::NORMALS){
|
||||
uninstV3d(VERT_FLOAT3,
|
||||
&geo->morphTargets[0].normals[3*inst->minVert],
|
||||
&geo->morphTargets[0].normals[inst->minVert],
|
||||
src, inst->numVertices, inst->stride);
|
||||
src += 12;
|
||||
}
|
||||
|
||||
inst->vertexAlpha = 0;
|
||||
if(geo->flags & Geometry::PRELIT){
|
||||
uninstColor(VERT_ARGB, &geo->colors[4*inst->minVert], src,
|
||||
uninstColor(VERT_ARGB, &geo->colors[inst->minVert], src,
|
||||
inst->numVertices, inst->stride);
|
||||
src += 4;
|
||||
}
|
||||
|
||||
for(int32 i = 0; i < geo->numTexCoordSets; i++){
|
||||
uninstTexCoords(VERT_FLOAT2, &geo->texCoords[i][2*inst->minVert], src,
|
||||
uninstTexCoords(VERT_FLOAT2, &geo->texCoords[i][inst->minVert], src,
|
||||
inst->numVertices, inst->stride);
|
||||
src += 8;
|
||||
}
|
||||
|
@ -481,7 +481,7 @@ readNativeTexture(Stream *stream)
|
|||
{
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
#include "rwd3d8.h"
|
||||
|
||||
|
@ -23,28 +24,31 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
{
|
||||
RawMatrix world;
|
||||
|
||||
d3d::lightingCB();
|
||||
|
||||
Geometry *geo = atomic->geometry;
|
||||
d3d::setRenderState(D3DRS_LIGHTING, !!(geo->flags & rw::Geometry::LIGHT));
|
||||
|
||||
Frame *f = atomic->getFrame();
|
||||
convMatrix(&world, f->getLTM());
|
||||
device->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world);
|
||||
d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world);
|
||||
|
||||
InstanceData *inst = header->inst;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
d3d::setTexture(0, inst->material->texture);
|
||||
d3d::setMaterial(inst->material);
|
||||
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
if(geo->flags & Geometry::PRELIT)
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
|
||||
device->SetFVF(inst->vertexShader);
|
||||
device->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
|
||||
device->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer);
|
||||
d3ddevice->SetFVF(inst->vertexShader);
|
||||
d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)inst->vertexBuffer, 0, inst->stride);
|
||||
d3ddevice->SetIndices((IDirect3DIndexBuffer9*)inst->indexBuffer);
|
||||
uint32 numPrim = inst->primType == D3DPT_TRIANGLESTRIP ? inst->numIndices-2 : inst->numIndices/3;
|
||||
d3d::flushCache();
|
||||
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex,
|
||||
0, inst->numVertices, 0, numPrim);
|
||||
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)inst->primType, inst->baseIndex,
|
||||
0, inst->numVertices, 0, numPrim);
|
||||
inst++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,15 +31,15 @@ static VertexElement _d3ddec_end = {0xFF,0,D3DDECLTYPE_UNUSED,0,0,0};
|
|||
void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
driver[PLATFORM_D3D9]->defaultPipeline = makeDefaultPipeline();
|
||||
engine->driver[PLATFORM_D3D9]->defaultPipeline = makeDefaultPipeline();
|
||||
|
||||
driver[PLATFORM_D3D9]->rasterNativeOffset = nativeRasterOffset;
|
||||
driver[PLATFORM_D3D9]->rasterCreate = rasterCreate;
|
||||
driver[PLATFORM_D3D9]->rasterLock = rasterLock;
|
||||
driver[PLATFORM_D3D9]->rasterUnlock = rasterUnlock;
|
||||
driver[PLATFORM_D3D9]->rasterNumLevels = rasterNumLevels;
|
||||
driver[PLATFORM_D3D9]->rasterFromImage = rasterFromImage;
|
||||
driver[PLATFORM_D3D9]->rasterToImage = rasterToImage;
|
||||
engine->driver[PLATFORM_D3D9]->rasterNativeOffset = nativeRasterOffset;
|
||||
engine->driver[PLATFORM_D3D9]->rasterCreate = rasterCreate;
|
||||
engine->driver[PLATFORM_D3D9]->rasterLock = rasterLock;
|
||||
engine->driver[PLATFORM_D3D9]->rasterUnlock = rasterUnlock;
|
||||
engine->driver[PLATFORM_D3D9]->rasterNumLevels = rasterNumLevels;
|
||||
engine->driver[PLATFORM_D3D9]->rasterFromImage = rasterFromImage;
|
||||
engine->driver[PLATFORM_D3D9]->rasterToImage = rasterToImage;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ createVertexDeclaration(VertexElement *elements)
|
|||
{
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DVertexDeclaration9 *decl = 0;
|
||||
device->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &decl);
|
||||
d3ddevice->CreateVertexDeclaration((D3DVERTEXELEMENT9*)elements, &decl);
|
||||
return decl;
|
||||
#else
|
||||
int n = 0;
|
||||
|
@ -122,7 +122,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
|||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
@ -592,7 +592,7 @@ readNativeTexture(Stream *stream)
|
|||
{
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
#include "rwd3d9.h"
|
||||
|
||||
|
@ -23,29 +24,32 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
{
|
||||
RawMatrix world;
|
||||
|
||||
d3d::lightingCB();
|
||||
|
||||
Geometry *geo = atomic->geometry;
|
||||
d3d::setRenderState(D3DRS_LIGHTING, !!(geo->flags & rw::Geometry::LIGHT));
|
||||
|
||||
Frame *f = atomic->getFrame();
|
||||
convMatrix(&world, f->getLTM());
|
||||
device->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world);
|
||||
d3ddevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)&world);
|
||||
|
||||
device->SetStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer,
|
||||
0, header->vertexStream[0].stride);
|
||||
device->SetIndices((IDirect3DIndexBuffer9*)header->indexBuffer);
|
||||
device->SetVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration);
|
||||
d3ddevice->SetStreamSource(0, (IDirect3DVertexBuffer9*)header->vertexStream[0].vertexBuffer,
|
||||
0, header->vertexStream[0].stride);
|
||||
d3ddevice->SetIndices((IDirect3DIndexBuffer9*)header->indexBuffer);
|
||||
d3ddevice->SetVertexDeclaration((IDirect3DVertexDeclaration9*)header->vertexDeclaration);
|
||||
|
||||
InstanceData *inst = header->inst;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
d3d::setTexture(0, inst->material->texture);
|
||||
d3d::setMaterial(inst->material);
|
||||
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
|
||||
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
if(geo->flags & Geometry::PRELIT)
|
||||
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
d3d::flushCache();
|
||||
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
|
||||
0, inst->numVertices,
|
||||
inst->startIndex, inst->numPrimitives);
|
||||
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,
|
||||
0, inst->numVertices,
|
||||
inst->startIndex, inst->numPrimitives);
|
||||
inst++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,562 @@
|
|||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
|
||||
namespace rw {
|
||||
namespace d3d {
|
||||
|
||||
#ifdef RW_D3D9
|
||||
|
||||
// cached RW render states
|
||||
static bool32 vertexAlpha;
|
||||
static bool32 textureAlpha;
|
||||
static uint32 srcblend, destblend;
|
||||
static uint32 zwrite;
|
||||
static uint32 ztest;
|
||||
static uint32 fogenable;
|
||||
static RGBA fogcolor;
|
||||
static uint32 alphafunc;
|
||||
static uint32 alpharef;
|
||||
|
||||
|
||||
#define MAXNUMSTATES D3DRS_BLENDOPALPHA
|
||||
#define MAXNUMSTAGES 8
|
||||
#define MAXNUMTEXSTATES D3DTSS_CONSTANT
|
||||
#define MAXNUMSAMPLERSTATES D3DSAMP_DMAPOFFSET
|
||||
|
||||
static int32 numDirtyStates;
|
||||
static uint32 dirtyStates[MAXNUMSTATES];
|
||||
static struct {
|
||||
uint32 value;
|
||||
bool32 dirty;
|
||||
} stateCache[MAXNUMSTATES];
|
||||
static uint32 d3dStates[MAXNUMSTATES];
|
||||
|
||||
static int32 numDirtyTextureStageStates;
|
||||
static struct {
|
||||
uint32 stage;
|
||||
uint32 type;
|
||||
} dirtyTextureStageStates[MAXNUMTEXSTATES*MAXNUMSTAGES];
|
||||
static struct {
|
||||
uint32 value;
|
||||
bool32 dirty;
|
||||
} textureStageStateCache[MAXNUMSTATES][MAXNUMSTAGES];
|
||||
static uint32 d3dTextureStageStates[MAXNUMSTATES][MAXNUMSTAGES];
|
||||
|
||||
static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES];
|
||||
|
||||
// TODO: not only rasters, make a struct
|
||||
static Raster *d3dRaster[MAXNUMSTAGES];
|
||||
|
||||
static D3DMATERIAL9 d3dmaterial;
|
||||
|
||||
// D3D render state
|
||||
|
||||
void
|
||||
setRenderState(uint32 state, uint32 value)
|
||||
{
|
||||
if(stateCache[state].value != value){
|
||||
stateCache[state].value = value;
|
||||
if(!stateCache[state].dirty){
|
||||
stateCache[state].dirty = 1;
|
||||
dirtyStates[numDirtyStates++] = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setTextureStageState(uint32 stage, uint32 type, uint32 value)
|
||||
{
|
||||
if(textureStageStateCache[type][stage].value != value){
|
||||
textureStageStateCache[type][stage].value = value;
|
||||
if(!textureStageStateCache[type][stage].dirty){
|
||||
textureStageStateCache[type][stage].dirty = 1;
|
||||
dirtyTextureStageStates[numDirtyTextureStageStates].stage = stage;
|
||||
dirtyTextureStageStates[numDirtyTextureStageStates].type = type;
|
||||
numDirtyTextureStageStates++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
flushCache(void)
|
||||
{
|
||||
uint32 s, t;
|
||||
uint32 v;
|
||||
for(int32 i = 0; i < numDirtyStates; i++){
|
||||
s = dirtyStates[i];
|
||||
v = stateCache[s].value;
|
||||
stateCache[s].dirty = 0;
|
||||
if(d3dStates[s] != v){
|
||||
d3ddevice->SetRenderState((D3DRENDERSTATETYPE)s, v);
|
||||
d3dStates[s] = v;
|
||||
}
|
||||
}
|
||||
numDirtyStates = 0;
|
||||
for(int32 i = 0; i < numDirtyTextureStageStates; i++){
|
||||
s = dirtyTextureStageStates[i].stage;
|
||||
t = dirtyTextureStageStates[i].type;
|
||||
v = textureStageStateCache[t][s].value;
|
||||
textureStageStateCache[t][s].dirty = 0;
|
||||
if(d3dTextureStageStates[t][s] != v){
|
||||
d3ddevice->SetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, v);
|
||||
d3dTextureStageStates[t][s] = v;
|
||||
}
|
||||
}
|
||||
numDirtyTextureStageStates = 0;
|
||||
}
|
||||
|
||||
void
|
||||
setSamplerState(uint32 stage, uint32 type, uint32 value)
|
||||
{
|
||||
if(d3dSamplerStates[type][stage] != value){
|
||||
d3ddevice->SetSamplerState(stage, (D3DSAMPLERSTATETYPE)type, value);
|
||||
d3dSamplerStates[type][stage] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// RW render state
|
||||
|
||||
static void
|
||||
setVertexAlpha(bool32 enable)
|
||||
{
|
||||
if(vertexAlpha != enable){
|
||||
if(!textureAlpha){
|
||||
setRenderState(D3DRS_ALPHABLENDENABLE, enable);
|
||||
setRenderState(D3DRS_ALPHATESTENABLE, enable);
|
||||
}
|
||||
vertexAlpha = enable;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 blendMap[] = {
|
||||
D3DBLEND_ZERO,
|
||||
D3DBLEND_ONE,
|
||||
D3DBLEND_SRCCOLOR,
|
||||
D3DBLEND_INVSRCCOLOR,
|
||||
D3DBLEND_SRCALPHA,
|
||||
D3DBLEND_INVSRCALPHA,
|
||||
D3DBLEND_DESTALPHA,
|
||||
D3DBLEND_INVDESTALPHA,
|
||||
D3DBLEND_DESTCOLOR,
|
||||
D3DBLEND_INVDESTCOLOR,
|
||||
D3DBLEND_SRCALPHASAT
|
||||
};
|
||||
|
||||
uint32 alphafuncMap[] = {
|
||||
D3DCMP_ALWAYS,
|
||||
D3DCMP_GREATEREQUAL,
|
||||
D3DCMP_LESS
|
||||
};
|
||||
|
||||
static void
|
||||
setRwRenderState(int32 state, uint32 value)
|
||||
{
|
||||
uint32 bval = value ? TRUE : FALSE;
|
||||
switch(state){
|
||||
case VERTEXALPHA:
|
||||
setVertexAlpha(bval);
|
||||
break;
|
||||
case SRCBLEND:
|
||||
if(srcblend != value){
|
||||
srcblend = value;
|
||||
setRenderState(D3DRS_SRCBLEND, blendMap[value]);
|
||||
}
|
||||
break;
|
||||
case DESTBLEND:
|
||||
if(destblend != value){
|
||||
destblend = value;
|
||||
setRenderState(D3DRS_DESTBLEND, blendMap[value]);
|
||||
}
|
||||
break;
|
||||
case ZTESTENABLE:
|
||||
if(ztest != bval){
|
||||
ztest = bval;
|
||||
setRenderState(D3DRS_ZENABLE, ztest);
|
||||
}
|
||||
break;
|
||||
case ZWRITEENABLE:
|
||||
if(zwrite != bval){
|
||||
zwrite = bval;
|
||||
setRenderState(D3DRS_ZWRITEENABLE, zwrite);
|
||||
}
|
||||
break;
|
||||
case FOGENABLE:
|
||||
if(fogenable != bval){
|
||||
fogenable = bval;
|
||||
setRenderState(D3DRS_FOGENABLE, fogenable);
|
||||
};
|
||||
break;
|
||||
case FOGCOLOR:{
|
||||
RGBA c = *(RGBA*)&value;
|
||||
if(!equal(fogcolor, c)){
|
||||
fogcolor = c;
|
||||
setRenderState(D3DRS_FOGCOLOR, D3DCOLOR_RGBA(c.red, c.green, c.blue, c.alpha));
|
||||
}} break;
|
||||
case ALPHATESTFUNC:
|
||||
if(alphafunc != value){
|
||||
alphafunc = value;
|
||||
setRenderState(D3DRS_ALPHAFUNC, alphafuncMap[alphafunc]);
|
||||
}
|
||||
break;
|
||||
case ALPHATESTREF:
|
||||
if(alpharef != value){
|
||||
alpharef = value;
|
||||
setRenderState(D3DRS_ALPHAREF, alpharef);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32
|
||||
getRwRenderState(int32 state)
|
||||
{
|
||||
switch(state){
|
||||
case VERTEXALPHA:
|
||||
return vertexAlpha;
|
||||
case SRCBLEND:
|
||||
return srcblend;
|
||||
case DESTBLEND:
|
||||
return destblend;
|
||||
case ZTESTENABLE:
|
||||
return ztest;
|
||||
case ZWRITEENABLE:
|
||||
return zwrite;
|
||||
case FOGENABLE:
|
||||
return fogenable;
|
||||
case FOGCOLOR:
|
||||
return *(uint32*)&fogcolor;
|
||||
case ALPHATESTFUNC:
|
||||
return alphafunc;
|
||||
case ALPHATESTREF:
|
||||
return alpharef;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
setRasterStage(uint32 stage, Raster *raster)
|
||||
{
|
||||
bool32 alpha;
|
||||
D3dRaster *d3draster = nil;
|
||||
if(raster != d3dRaster[stage]){
|
||||
d3dRaster[stage] = raster;
|
||||
if(raster){
|
||||
d3draster = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||
d3ddevice->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture);
|
||||
alpha = d3draster->hasAlpha;
|
||||
}else{
|
||||
d3ddevice->SetTexture(stage, nil);
|
||||
alpha = 0;
|
||||
}
|
||||
if(stage == 0){
|
||||
if(textureAlpha != alpha){
|
||||
textureAlpha = alpha;
|
||||
if(!vertexAlpha){
|
||||
setRenderState(D3DRS_ALPHABLENDENABLE, alpha);
|
||||
setRenderState(D3DRS_ALPHATESTENABLE, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setTexture(uint32 stage, Texture *tex)
|
||||
{
|
||||
static DWORD filternomip[] = {
|
||||
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||
D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||
D3DTEXF_POINT, D3DTEXF_LINEAR
|
||||
};
|
||||
static DWORD wrap[] = {
|
||||
0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
|
||||
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
|
||||
};
|
||||
if(tex == nil){
|
||||
setRasterStage(stage, nil);
|
||||
return;
|
||||
}
|
||||
if(tex->raster){
|
||||
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
|
||||
}
|
||||
setRasterStage(stage, tex->raster);
|
||||
}
|
||||
|
||||
void
|
||||
setMaterial(Material *mat)
|
||||
{
|
||||
D3DMATERIAL9 mat9;
|
||||
D3DCOLORVALUE black = { 0, 0, 0, 0 };
|
||||
float ambmult = mat->surfaceProps.ambient/255.0f;
|
||||
float diffmult = mat->surfaceProps.diffuse/255.0f;
|
||||
mat9.Ambient.r = mat->color.red*ambmult;
|
||||
mat9.Ambient.g = mat->color.green*ambmult;
|
||||
mat9.Ambient.b = mat->color.blue*ambmult;
|
||||
mat9.Ambient.a = mat->color.alpha*ambmult;
|
||||
mat9.Diffuse.r = mat->color.red*diffmult;
|
||||
mat9.Diffuse.g = mat->color.green*diffmult;
|
||||
mat9.Diffuse.b = mat->color.blue*diffmult;
|
||||
mat9.Diffuse.a = mat->color.alpha*diffmult;
|
||||
mat9.Power = 0.0f;
|
||||
mat9.Emissive = black;
|
||||
mat9.Specular = black;
|
||||
if(d3dmaterial.Diffuse.r != mat9.Diffuse.r ||
|
||||
d3dmaterial.Diffuse.g != mat9.Diffuse.g ||
|
||||
d3dmaterial.Diffuse.b != mat9.Diffuse.b ||
|
||||
d3dmaterial.Diffuse.a != mat9.Diffuse.a ||
|
||||
d3dmaterial.Ambient.r != mat9.Ambient.r ||
|
||||
d3dmaterial.Ambient.g != mat9.Ambient.g ||
|
||||
d3dmaterial.Ambient.b != mat9.Ambient.b ||
|
||||
d3dmaterial.Ambient.a != mat9.Ambient.a){
|
||||
d3ddevice->SetMaterial(&mat9);
|
||||
d3dmaterial = mat9;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
beginUpdate(Camera *cam)
|
||||
{
|
||||
float view[16], proj[16];
|
||||
|
||||
// View Matrix
|
||||
Matrix inv;
|
||||
Matrix::invert(&inv, cam->getFrame()->getLTM());
|
||||
// Since we're looking into positive Z,
|
||||
// flip X to ge a left handed view space.
|
||||
view[0] = -inv.right.x;
|
||||
view[1] = inv.right.y;
|
||||
view[2] = inv.right.z;
|
||||
view[3] = 0.0f;
|
||||
view[4] = -inv.up.x;
|
||||
view[5] = inv.up.y;
|
||||
view[6] = inv.up.z;
|
||||
view[7] = 0.0f;
|
||||
view[8] = -inv.at.x;
|
||||
view[9] = inv.at.y;
|
||||
view[10] = inv.at.z;
|
||||
view[11] = 0.0f;
|
||||
view[12] = -inv.pos.x;
|
||||
view[13] = inv.pos.y;
|
||||
view[14] = inv.pos.z;
|
||||
view[15] = 1.0f;
|
||||
d3ddevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)view);
|
||||
|
||||
// Projection Matrix
|
||||
float32 invwx = 1.0f/cam->viewWindow.x;
|
||||
float32 invwy = 1.0f/cam->viewWindow.y;
|
||||
float32 invz = 1.0f/(cam->farPlane-cam->nearPlane);
|
||||
|
||||
proj[0] = invwx;
|
||||
proj[1] = 0.0f;
|
||||
proj[2] = 0.0f;
|
||||
proj[3] = 0.0f;
|
||||
|
||||
proj[4] = 0.0f;
|
||||
proj[5] = invwy;
|
||||
proj[6] = 0.0f;
|
||||
proj[7] = 0.0f;
|
||||
|
||||
proj[8] = cam->viewOffset.x*invwx;
|
||||
proj[9] = cam->viewOffset.y*invwy;
|
||||
proj[12] = -proj[8];
|
||||
proj[13] = -proj[9];
|
||||
if(cam->projection == Camera::PERSPECTIVE){
|
||||
proj[10] = cam->farPlane*invz;
|
||||
proj[11] = 1.0f;
|
||||
|
||||
proj[15] = 0.0f;
|
||||
}else{
|
||||
proj[10] = invz;
|
||||
proj[11] = 0.0f;
|
||||
|
||||
proj[15] = 1.0f;
|
||||
}
|
||||
proj[14] = -cam->nearPlane*proj[10];
|
||||
d3ddevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)proj);
|
||||
|
||||
// TODO: figure out where this is really done
|
||||
setRenderState(D3DRS_FOGSTART, *(uint32*)&cam->fogPlane);
|
||||
setRenderState(D3DRS_FOGEND, *(uint32*)&cam->farPlane);
|
||||
|
||||
// TODO: figure out when to call this
|
||||
d3ddevice->BeginScene();
|
||||
}
|
||||
|
||||
static void
|
||||
endUpdate(Camera *cam)
|
||||
{
|
||||
// TODO: figure out when to call this
|
||||
d3ddevice->EndScene();
|
||||
}
|
||||
|
||||
static void
|
||||
clearCamera(Camera *cam, RGBA *col, uint32 mode)
|
||||
{
|
||||
int flags = 0;
|
||||
if(mode & Camera::CLEARIMAGE)
|
||||
mode |= D3DCLEAR_TARGET;
|
||||
if(mode & Camera::CLEARZ)
|
||||
mode |= D3DCLEAR_ZBUFFER;
|
||||
D3DCOLOR c = D3DCOLOR_RGBA(col->red, col->green, col->blue, col->alpha);
|
||||
d3ddevice->Clear(0, 0, mode, c, 1.0f, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
showRaster(Raster *raster)
|
||||
{
|
||||
// TODO: do this properly!
|
||||
d3ddevice->Present(nil, nil, 0, nil);
|
||||
}
|
||||
|
||||
// taken from Frank Luna's d3d9 book
|
||||
static int
|
||||
startD3D(EngineStartParams *params)
|
||||
{
|
||||
HWND win = params->window;
|
||||
bool windowed = true;
|
||||
|
||||
HRESULT hr = 0;
|
||||
IDirect3D9 *d3d9 = 0;
|
||||
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
if(!d3d9){
|
||||
RWERROR((ERR_GENERAL, "Direct3DCreate9() failed"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
D3DCAPS9 caps;
|
||||
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
|
||||
int vp = 0;
|
||||
if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
|
||||
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
|
||||
else
|
||||
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(win, &rect);
|
||||
int width = rect.right - rect.left;
|
||||
int height = rect.bottom - rect.top;
|
||||
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
d3dpp.BackBufferWidth = width;
|
||||
d3dpp.BackBufferHeight = height;
|
||||
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
||||
d3dpp.BackBufferCount = 1;
|
||||
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
d3dpp.MultiSampleQuality = 0;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.hDeviceWindow = win;
|
||||
d3dpp.Windowed = windowed;
|
||||
d3dpp.EnableAutoDepthStencil = true;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
|
||||
d3dpp.Flags = 0;
|
||||
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
|
||||
IDirect3DDevice9 *dev;
|
||||
hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, win,
|
||||
vp, &d3dpp, &dev);
|
||||
if(FAILED(hr)){
|
||||
// try again using a 16-bit depth buffer
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||||
|
||||
hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
|
||||
win, vp, &d3dpp, &dev);
|
||||
|
||||
if(FAILED(hr)){
|
||||
RWERROR((ERR_GENERAL, "CreateDevice() failed"));
|
||||
d3d9->Release();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
d3d9->Release();
|
||||
d3d::d3ddevice = dev;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
stopD3D(void)
|
||||
{
|
||||
d3d::d3ddevice->Release();
|
||||
d3d::d3ddevice = nil;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
initD3D(void)
|
||||
{
|
||||
// TODO: do some real stuff here
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
|
||||
alphafunc = ALPHAGREATEREQUAL;
|
||||
d3ddevice->SetRenderState(D3DRS_ALPHAREF, 10);
|
||||
alpharef = 10;
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
fogenable = 0;
|
||||
d3ddevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
|
||||
// TODO: more fog stuff
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
|
||||
d3ddevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
srcblend = BLENDSRCALPHA;
|
||||
d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
destblend = BLENDINVSRCALPHA;
|
||||
d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 0);
|
||||
vertexAlpha = 0;
|
||||
textureAlpha = 0;
|
||||
|
||||
setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
// setTextureStageState(0, D3DTSS_CONSTANT, 0xFFFFFFFF);
|
||||
// setTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
// setTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
|
||||
// setTextureStageState(0, D3DTSS_COLOROP, D3DTA_CONSTANT);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
deviceSystem(DeviceReq req, void *arg0)
|
||||
{
|
||||
switch(req){
|
||||
case DEVICESTART:
|
||||
return startD3D((EngineStartParams*)arg0);
|
||||
case DEVICEINIT:
|
||||
return initD3D();
|
||||
case DEVICESTOP:
|
||||
return stopD3D();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Device renderdevice = {
|
||||
0.0f, 1.0f,
|
||||
d3d::beginUpdate,
|
||||
d3d::endUpdate,
|
||||
d3d::clearCamera,
|
||||
d3d::showRaster,
|
||||
d3d::setRwRenderState,
|
||||
d3d::getRwRenderState,
|
||||
null::im2DRenderIndexedPrimitive,
|
||||
d3d::deviceSystem,
|
||||
};
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,251 +0,0 @@
|
|||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
|
||||
namespace rw {
|
||||
namespace d3d {
|
||||
|
||||
#ifdef RW_D3D9
|
||||
|
||||
#define MAXNUMSTATES D3DRS_BLENDOPALPHA
|
||||
#define MAXNUMSTAGES 8
|
||||
#define MAXNUMTEXSTATES D3DTSS_CONSTANT
|
||||
#define MAXNUMSAMPLERSTATES D3DSAMP_DMAPOFFSET
|
||||
|
||||
static int32 numDirtyStates;
|
||||
static uint32 dirtyStates[MAXNUMSTATES];
|
||||
static struct {
|
||||
uint32 value;
|
||||
bool32 dirty;
|
||||
} stateCache[MAXNUMSTATES];
|
||||
static uint32 d3dStates[MAXNUMSTATES];
|
||||
|
||||
static int32 numDirtyTextureStageStates;
|
||||
static struct {
|
||||
uint32 stage;
|
||||
uint32 type;
|
||||
} dirtyTextureStageStates[MAXNUMTEXSTATES*MAXNUMSTAGES];
|
||||
static struct {
|
||||
uint32 value;
|
||||
bool32 dirty;
|
||||
} textureStageStateCache[MAXNUMSTATES][MAXNUMSTAGES];
|
||||
static uint32 d3dTextureStageStates[MAXNUMSTATES][MAXNUMSTAGES];
|
||||
|
||||
static uint32 d3dSamplerStates[MAXNUMSAMPLERSTATES][MAXNUMSTAGES];
|
||||
|
||||
static Raster *d3dRaster[MAXNUMSTAGES];
|
||||
|
||||
static D3DMATERIAL9 d3dmaterial;
|
||||
|
||||
void
|
||||
setRenderState(uint32 state, uint32 value)
|
||||
{
|
||||
if(stateCache[state].value != value){
|
||||
stateCache[state].value = value;
|
||||
if(!stateCache[state].dirty){
|
||||
stateCache[state].dirty = 1;
|
||||
dirtyStates[numDirtyStates++] = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setTextureStageState(uint32 stage, uint32 type, uint32 value)
|
||||
{
|
||||
if(textureStageStateCache[type][stage].value != value){
|
||||
textureStageStateCache[type][stage].value = value;
|
||||
if(!textureStageStateCache[type][stage].dirty){
|
||||
textureStageStateCache[type][stage].dirty = 1;
|
||||
dirtyTextureStageStates[numDirtyTextureStageStates].stage = stage;
|
||||
dirtyTextureStageStates[numDirtyTextureStageStates].type = type;
|
||||
numDirtyTextureStageStates++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
flushCache(void)
|
||||
{
|
||||
uint32 s, t;
|
||||
uint32 v;
|
||||
for(int32 i = 0; i < numDirtyStates; i++){
|
||||
s = dirtyStates[i];
|
||||
v = stateCache[s].value;
|
||||
stateCache[s].dirty = 0;
|
||||
if(d3dStates[s] != v){
|
||||
device->SetRenderState((D3DRENDERSTATETYPE)s, v);
|
||||
d3dStates[s] = v;
|
||||
}
|
||||
}
|
||||
numDirtyStates = 0;
|
||||
for(int32 i = 0; i < numDirtyTextureStageStates; i++){
|
||||
s = dirtyTextureStageStates[i].stage;
|
||||
t = dirtyTextureStageStates[i].type;
|
||||
v = textureStageStateCache[t][s].value;
|
||||
textureStageStateCache[t][s].dirty = 0;
|
||||
if(d3dTextureStageStates[t][s] != v){
|
||||
device->SetTextureStageState(s, (D3DTEXTURESTAGESTATETYPE)t, v);
|
||||
d3dTextureStageStates[t][s] = v;
|
||||
}
|
||||
}
|
||||
numDirtyTextureStageStates = 0;
|
||||
}
|
||||
|
||||
void
|
||||
setSamplerState(uint32 stage, uint32 type, uint32 value)
|
||||
{
|
||||
if(d3dSamplerStates[type][stage] != value){
|
||||
device->SetSamplerState(stage, (D3DSAMPLERSTATETYPE)type, value);
|
||||
d3dSamplerStates[type][stage] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setRasterStage(uint32 stage, Raster *raster)
|
||||
{
|
||||
D3dRaster *d3draster = nil;
|
||||
if(raster != d3dRaster[stage]){
|
||||
d3dRaster[stage] = raster;
|
||||
if(raster){
|
||||
d3draster = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
|
||||
device->SetTexture(stage, (IDirect3DTexture9*)d3draster->texture);
|
||||
}else
|
||||
device->SetTexture(stage, nil);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setTexture(uint32 stage, Texture *tex)
|
||||
{
|
||||
static DWORD filternomip[] = {
|
||||
0, D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||
D3DTEXF_POINT, D3DTEXF_LINEAR,
|
||||
D3DTEXF_POINT, D3DTEXF_LINEAR
|
||||
};
|
||||
static DWORD wrap[] = {
|
||||
0, D3DTADDRESS_WRAP, D3DTADDRESS_MIRROR,
|
||||
D3DTADDRESS_CLAMP, D3DTADDRESS_BORDER
|
||||
};
|
||||
if(tex == nil){
|
||||
setRasterStage(stage, nil);
|
||||
return;
|
||||
}
|
||||
if(tex->raster){
|
||||
setSamplerState(stage, D3DSAMP_MAGFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
setSamplerState(stage, D3DSAMP_MINFILTER, filternomip[tex->filterAddressing & 0xFF]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSU, wrap[(tex->filterAddressing >> 8) & 0xF]);
|
||||
setSamplerState(stage, D3DSAMP_ADDRESSV, wrap[(tex->filterAddressing >> 12) & 0xF]);
|
||||
}
|
||||
setRasterStage(stage, tex->raster);
|
||||
}
|
||||
|
||||
void
|
||||
setMaterial(Material *mat)
|
||||
{
|
||||
D3DMATERIAL9 mat9;
|
||||
D3DCOLORVALUE black = { 0, 0, 0, 0 };
|
||||
float ambmult = mat->surfaceProps.ambient/255.0f;
|
||||
float diffmult = mat->surfaceProps.diffuse/255.0f;
|
||||
mat9.Ambient.r = mat->color.red*ambmult;
|
||||
mat9.Ambient.g = mat->color.green*ambmult;
|
||||
mat9.Ambient.b = mat->color.blue*ambmult;
|
||||
mat9.Ambient.a = mat->color.alpha*ambmult;
|
||||
mat9.Diffuse.r = mat->color.red*diffmult;
|
||||
mat9.Diffuse.g = mat->color.green*diffmult;
|
||||
mat9.Diffuse.b = mat->color.blue*diffmult;
|
||||
mat9.Diffuse.a = mat->color.alpha*diffmult;
|
||||
mat9.Power = 0.0f;
|
||||
mat9.Emissive = black;
|
||||
mat9.Specular = black;
|
||||
if(d3dmaterial.Diffuse.r != mat9.Diffuse.r ||
|
||||
d3dmaterial.Diffuse.g != mat9.Diffuse.g ||
|
||||
d3dmaterial.Diffuse.b != mat9.Diffuse.b ||
|
||||
d3dmaterial.Diffuse.a != mat9.Diffuse.a ||
|
||||
d3dmaterial.Ambient.r != mat9.Ambient.r ||
|
||||
d3dmaterial.Ambient.g != mat9.Ambient.g ||
|
||||
d3dmaterial.Ambient.b != mat9.Ambient.b ||
|
||||
d3dmaterial.Ambient.a != mat9.Ambient.a){
|
||||
device->SetMaterial(&mat9);
|
||||
d3dmaterial = mat9;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
beginUpdate(Camera *cam)
|
||||
{
|
||||
float view[16], proj[16];
|
||||
|
||||
// View Matrix
|
||||
Matrix inv;
|
||||
Matrix::invertOrthonormal(&inv, cam->getFrame()->getLTM());
|
||||
// Since we're looking into positive Z,
|
||||
// flip X to ge a left handed view space.
|
||||
view[0] = -inv.right.x;
|
||||
view[1] = inv.right.y;
|
||||
view[2] = inv.right.z;
|
||||
view[3] = 0.0f;
|
||||
view[4] = -inv.up.x;
|
||||
view[5] = inv.up.y;
|
||||
view[6] = inv.up.z;
|
||||
view[7] = 0.0f;
|
||||
view[8] = -inv.at.x;
|
||||
view[9] = inv.at.y;
|
||||
view[10] = inv.at.z;
|
||||
view[11] = 0.0f;
|
||||
view[12] = -inv.pos.x;
|
||||
view[13] = inv.pos.y;
|
||||
view[14] = inv.pos.z;
|
||||
view[15] = 1.0f;
|
||||
device->SetTransform(D3DTS_VIEW, (D3DMATRIX*)view);
|
||||
|
||||
// Projection Matrix
|
||||
float32 invwx = 1.0f/cam->viewWindow.x;
|
||||
float32 invwy = 1.0f/cam->viewWindow.y;
|
||||
float32 invz = 1.0f/(cam->farPlane-cam->nearPlane);
|
||||
|
||||
proj[0] = invwx;
|
||||
proj[1] = 0.0f;
|
||||
proj[2] = 0.0f;
|
||||
proj[3] = 0.0f;
|
||||
|
||||
proj[4] = 0.0f;
|
||||
proj[5] = invwy;
|
||||
proj[6] = 0.0f;
|
||||
proj[7] = 0.0f;
|
||||
|
||||
proj[8] = cam->viewOffset.x*invwx;
|
||||
proj[9] = cam->viewOffset.y*invwy;
|
||||
proj[12] = -proj[8];
|
||||
proj[13] = -proj[9];
|
||||
if(cam->projection == Camera::PERSPECTIVE){
|
||||
proj[10] = cam->farPlane*invz;
|
||||
proj[11] = 1.0f;
|
||||
|
||||
proj[15] = 0.0f;
|
||||
}else{
|
||||
proj[10] = invz;
|
||||
proj[11] = 0.0f;
|
||||
|
||||
proj[15] = 1.0f;
|
||||
}
|
||||
proj[14] = -cam->nearPlane*proj[10];
|
||||
device->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)proj);
|
||||
}
|
||||
|
||||
void
|
||||
initializeRender(void)
|
||||
{
|
||||
engine->beginUpdate = beginUpdate;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "rwd3d.h"
|
||||
|
||||
namespace rw {
|
||||
namespace d3d {
|
||||
|
||||
#ifdef RW_D3D9
|
||||
IDirect3DDevice9 *d3ddevice = nil;
|
||||
|
||||
#define MAX_LIGHTS 8
|
||||
|
||||
void
|
||||
lightingCB(void)
|
||||
{
|
||||
World *world;
|
||||
RGBAf ambLight = { 0.0, 0.0, 0.0, 1.0 };
|
||||
RGBA amb;
|
||||
D3DLIGHT9 light;
|
||||
light.Type = D3DLIGHT_DIRECTIONAL;
|
||||
//light.Diffuse = { 0.8f, 0.8f, 0.8f, 1.0f };
|
||||
light.Specular = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
light.Ambient = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
light.Position = { 0.0f, 0.0f, 0.0f };
|
||||
//light.Direction = { 0.0f, 0.0f, -1.0f };
|
||||
light.Range = 0.0f;
|
||||
light.Falloff = 0.0f;
|
||||
light.Attenuation0 = 0.0f;
|
||||
light.Attenuation1 = 0.0f;
|
||||
light.Attenuation2 = 0.0f;
|
||||
light.Theta = 0.0f;
|
||||
light.Phi = 0.0f;
|
||||
int n = 0;
|
||||
|
||||
world = (World*)engine->currentWorld;
|
||||
// only unpositioned lights right now
|
||||
FORLIST(lnk, world->directionalLights){
|
||||
Light *l = Light::fromWorld(lnk);
|
||||
if(l->getType() == Light::DIRECTIONAL){
|
||||
if(n >= MAX_LIGHTS)
|
||||
continue;
|
||||
light.Diffuse = *(D3DCOLORVALUE*)&l->color;
|
||||
light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at;
|
||||
d3ddevice->SetLight(n, &light);
|
||||
d3ddevice->LightEnable(n, TRUE);
|
||||
n++;
|
||||
}else if(l->getType() == Light::AMBIENT){
|
||||
ambLight.red += l->color.red;
|
||||
ambLight.green += l->color.green;
|
||||
ambLight.blue += l->color.blue;
|
||||
}
|
||||
}
|
||||
for(; n < MAX_LIGHTS; n++)
|
||||
d3ddevice->LightEnable(n, FALSE);
|
||||
convColor(&amb, &ambLight);
|
||||
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA(amb.red, amb.green, amb.blue, amb.alpha));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
|
@ -4,14 +4,23 @@
|
|||
#endif
|
||||
|
||||
namespace rw {
|
||||
namespace d3d {
|
||||
|
||||
void initializeRender(void);
|
||||
#ifdef RW_D3D9
|
||||
struct EngineStartParams
|
||||
{
|
||||
HWND window;
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace d3d {
|
||||
|
||||
extern bool32 isP8supported;
|
||||
|
||||
#ifdef RW_D3D9
|
||||
extern IDirect3DDevice9 *device;
|
||||
extern IDirect3DDevice9 *d3ddevice;
|
||||
extern Device renderdevice;
|
||||
|
||||
void lightingCB(void);
|
||||
#else
|
||||
enum {
|
||||
D3DLOCK_NOSYSLOCK = 0, // ignored
|
||||
|
|
|
@ -21,13 +21,13 @@ namespace xbox {
|
|||
void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
driver[PLATFORM_XBOX]->defaultPipeline = makeDefaultPipeline();
|
||||
engine->driver[PLATFORM_XBOX]->defaultPipeline = makeDefaultPipeline();
|
||||
|
||||
driver[PLATFORM_XBOX]->rasterNativeOffset = nativeRasterOffset;
|
||||
driver[PLATFORM_XBOX]->rasterCreate = rasterCreate;
|
||||
driver[PLATFORM_XBOX]->rasterLock = rasterLock;
|
||||
driver[PLATFORM_XBOX]->rasterUnlock = rasterUnlock;
|
||||
driver[PLATFORM_XBOX]->rasterNumLevels = rasterNumLevels;
|
||||
engine->driver[PLATFORM_XBOX]->rasterNativeOffset = nativeRasterOffset;
|
||||
engine->driver[PLATFORM_XBOX]->rasterCreate = rasterCreate;
|
||||
engine->driver[PLATFORM_XBOX]->rasterLock = rasterLock;
|
||||
engine->driver[PLATFORM_XBOX]->rasterUnlock = rasterUnlock;
|
||||
engine->driver[PLATFORM_XBOX]->rasterNumLevels = rasterNumLevels;
|
||||
// TODO: from image
|
||||
|
||||
return o;
|
||||
|
@ -71,7 +71,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
|||
uint32 vers;
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
@ -622,7 +622,7 @@ readNativeTexture(Stream *stream)
|
|||
{
|
||||
uint32 vers, platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
|
|
@ -35,7 +35,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
|||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 vers, platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, &vers)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
|
@ -15,22 +16,55 @@
|
|||
#include "gl/rwgl3.h"
|
||||
#include "gl/rwwdgl.h"
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
|
||||
namespace rw {
|
||||
|
||||
Engine *engine;
|
||||
Driver *driver[NUM_PLATFORMS];
|
||||
PluginList Driver::s_plglist[NUM_PLATFORMS];
|
||||
Engine::State Engine::state = Dead;
|
||||
|
||||
void
|
||||
// This function mainly registers engine plugins
|
||||
// RW initializes memory related things here too and
|
||||
// uses more plugins
|
||||
// TODO: do this^ ?
|
||||
bool32
|
||||
Engine::init(void)
|
||||
{
|
||||
engine = new Engine;
|
||||
PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil };
|
||||
if(engine || Engine::state != Dead){
|
||||
RWERROR((ERR_ENGINEINIT));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil };
|
||||
for(uint i = 0; i < NUM_PLATFORMS; i++)
|
||||
Driver::s_plglist[i] = init;
|
||||
|
||||
Frame::dirtyList.init();
|
||||
// Register plugins
|
||||
// TODO: these are wrong
|
||||
ps2::initializePlatform();
|
||||
xbox::initializePlatform();
|
||||
d3d8::initializePlatform();
|
||||
d3d9::initializePlatform();
|
||||
wdgl::initializePlatform();
|
||||
gl3::initializePlatform();
|
||||
|
||||
Engine::state = Initialized;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// This is where RW allocates the engine and e.g. opens d3d
|
||||
// TODO: this will take an argument with device specific data (HWND &c.)
|
||||
bool32
|
||||
Engine::open(void)
|
||||
{
|
||||
if(engine || Engine::state != Initialized){
|
||||
RWERROR((ERR_ENGINEOPEN));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate engine
|
||||
engine = (Engine*)malloc(sizeof(Engine));
|
||||
engine->currentCamera = nil;
|
||||
engine->currentWorld = nil;
|
||||
engine->currentTexDictionary = nil;
|
||||
|
@ -38,45 +72,78 @@ Engine::init(void)
|
|||
engine->loadTextures = 1;
|
||||
engine->makeDummies = 1;
|
||||
|
||||
engine->beginUpdate = null::beginUpdate;
|
||||
engine->endUpdate = null::endUpdate;
|
||||
engine->clearCamera = null::clearCamera;
|
||||
engine->setRenderState = null::setRenderState;
|
||||
engine->getRenderState = null::getRenderState;
|
||||
engine->im2DRenderIndexedPrimitive = null::im2DRenderIndexedPrimitive;
|
||||
engine->zNear = 0.0f; // random values
|
||||
engine->zFar = 1.0f;
|
||||
// Initialize device
|
||||
// Device and possibly OS specific!
|
||||
#ifdef RW_PS2
|
||||
engine->device = ps2::renderdevice;
|
||||
#elif RW_GL3
|
||||
engine->device = gl3::renderdevice;
|
||||
#elif RW_D3D9
|
||||
engine->device = d3d::renderdevice;
|
||||
#else
|
||||
engine->device = null::renderdevice;
|
||||
#endif
|
||||
|
||||
ps2::initializePlatform();
|
||||
xbox::initializePlatform();
|
||||
d3d8::initializePlatform();
|
||||
d3d9::initializePlatform();
|
||||
wdgl::initializePlatform();
|
||||
gl3::initializePlatform();
|
||||
// TODO: open device; create d3d object/get video mode
|
||||
|
||||
// TODO: init driver functions
|
||||
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
|
||||
for(uint i = 0; i < NUM_PLATFORMS; i++){
|
||||
rw::engine->driver[i] = (Driver*)malloc(Driver::s_plglist[i].size);
|
||||
|
||||
engine->driver[i]->defaultPipeline = defpipe;
|
||||
|
||||
engine->driver[i]->rasterCreate = null::rasterCreate;
|
||||
engine->driver[i]->rasterLock = null::rasterLock;
|
||||
engine->driver[i]->rasterUnlock = null::rasterUnlock;
|
||||
engine->driver[i]->rasterNumLevels = null::rasterNumLevels;
|
||||
engine->driver[i]->rasterFromImage = null::rasterFromImage;
|
||||
engine->driver[i]->rasterToImage = null::rasterToImage;
|
||||
}
|
||||
|
||||
Engine::state = Opened;
|
||||
return 1;
|
||||
}
|
||||
|
||||
PluginList Driver::s_plglist[NUM_PLATFORMS];
|
||||
// This is where RW creates the actual rendering device
|
||||
// ans calls the engine plugin ctors
|
||||
bool32
|
||||
Engine::start(EngineStartParams *p)
|
||||
{
|
||||
if(engine == nil || Engine::state != Opened){
|
||||
RWERROR((ERR_ENGINESTART));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Start device
|
||||
engine->device.system(DEVICESTART, (void*)p);
|
||||
engine->device.system(DEVICEINIT, nil);
|
||||
|
||||
// TODO: construct engine plugins
|
||||
Frame::dirtyList.init();
|
||||
for(uint i = 0; i < NUM_PLATFORMS; i++)
|
||||
Driver::s_plglist[i].construct(rw::engine->driver[i]);
|
||||
|
||||
// TODO: finalize device start
|
||||
|
||||
Engine::state = Started;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
Driver::open(void)
|
||||
Engine::term(void)
|
||||
{
|
||||
ObjPipeline *defpipe = new ObjPipeline(PLATFORM_NULL);
|
||||
}
|
||||
|
||||
for(uint i = 0; i < NUM_PLATFORMS; i++){
|
||||
rw::driver[i] = (Driver*)malloc(s_plglist[i].size);
|
||||
void
|
||||
Engine::close(void)
|
||||
{
|
||||
}
|
||||
|
||||
driver[i]->defaultPipeline = defpipe;
|
||||
|
||||
driver[i]->rasterCreate = null::rasterCreate;
|
||||
driver[i]->rasterLock = null::rasterLock;
|
||||
driver[i]->rasterUnlock = null::rasterUnlock;
|
||||
driver[i]->rasterNumLevels = null::rasterNumLevels;
|
||||
driver[i]->rasterFromImage = null::rasterFromImage;
|
||||
driver[i]->rasterToImage = null::rasterToImage;
|
||||
|
||||
|
||||
s_plglist[i].construct(rw::driver[i]);
|
||||
}
|
||||
void
|
||||
Engine::stop(void)
|
||||
{
|
||||
engine->device.system(DEVICESTOP, nil);
|
||||
}
|
||||
|
||||
namespace null {
|
||||
|
@ -84,6 +151,7 @@ namespace null {
|
|||
void beginUpdate(Camera*) { }
|
||||
void endUpdate(Camera*) { }
|
||||
void clearCamera(Camera*,RGBA*,uint32) { }
|
||||
void showRaster(Raster*) { }
|
||||
|
||||
void setRenderState(int32, uint32) { }
|
||||
uint32 getRenderState(int32) { return 0; }
|
||||
|
@ -129,5 +197,23 @@ rasterToImage(Raster*)
|
|||
return nil;
|
||||
}
|
||||
|
||||
int
|
||||
deviceSystem(DeviceReq req, void *arg0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Device renderdevice = {
|
||||
0.0f, 1.0f,
|
||||
null::beginUpdate,
|
||||
null::endUpdate,
|
||||
null::clearCamera,
|
||||
null::showRaster,
|
||||
null::setRenderState,
|
||||
null::getRenderState,
|
||||
null::im2DRenderIndexedPrimitive,
|
||||
null::deviceSystem
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace rw {
|
||||
|
||||
LinkList Frame::dirtyList;
|
||||
PluginList Frame::s_plglist = { sizeof(Frame), sizeof(Frame), nil, nil };
|
||||
|
||||
Frame*
|
||||
Frame::create(void)
|
||||
|
@ -269,6 +270,13 @@ Frame::scale(V3d *scl, CombineOp op)
|
|||
updateObjects();
|
||||
}
|
||||
|
||||
void
|
||||
Frame::transform(Matrix *mat, CombineOp op)
|
||||
{
|
||||
this->matrix.transform(mat, op);
|
||||
updateObjects();
|
||||
}
|
||||
|
||||
void
|
||||
Frame::updateObjects(void)
|
||||
{
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
|
||||
namespace rw {
|
||||
|
||||
PluginList Geometry::s_plglist = { sizeof(Geometry), sizeof(Geometry), nil, nil };
|
||||
PluginList Material::s_plglist = { sizeof(Material), sizeof(Material), nil, nil };
|
||||
|
||||
SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
Geometry*
|
||||
|
@ -288,8 +291,8 @@ Geometry::calculateBoundingSphere(void)
|
|||
{
|
||||
for(int32 i = 0; i < this->numMorphTargets; i++){
|
||||
MorphTarget *m = &this->morphTargets[i];
|
||||
V3d min { 1000000.0f, 1000000.0f, 1000000.0f };
|
||||
V3d max { -1000000.0f, -1000000.0f, -1000000.0f };
|
||||
V3d min = { 1000000.0f, 1000000.0f, 1000000.0f };
|
||||
V3d max = { -1000000.0f, -1000000.0f, -1000000.0f };
|
||||
V3d *v = m->vertices;
|
||||
for(int32 j = 0; j < this->numVertices; j++){
|
||||
if(v->x > max.x) max.x = v->x;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
#include "rwanim.h"
|
||||
#include "rwplugins.h"
|
||||
#include "ps2/rwps2.h"
|
||||
|
|
|
@ -26,14 +26,14 @@ void*
|
|||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
#ifdef RW_OPENGL
|
||||
driver[PLATFORM_GL3]->defaultPipeline = makeDefaultPipeline();
|
||||
engine->driver[PLATFORM_GL3]->defaultPipeline = makeDefaultPipeline();
|
||||
#endif
|
||||
driver[PLATFORM_GL3]->rasterNativeOffset = nativeRasterOffset;
|
||||
driver[PLATFORM_GL3]->rasterCreate = rasterCreate;
|
||||
driver[PLATFORM_GL3]->rasterLock = rasterLock;
|
||||
driver[PLATFORM_GL3]->rasterUnlock = rasterUnlock;
|
||||
driver[PLATFORM_GL3]->rasterNumLevels = rasterNumLevels;
|
||||
driver[PLATFORM_GL3]->rasterFromImage = rasterFromImage;
|
||||
engine->driver[PLATFORM_GL3]->rasterNativeOffset = nativeRasterOffset;
|
||||
engine->driver[PLATFORM_GL3]->rasterCreate = rasterCreate;
|
||||
engine->driver[PLATFORM_GL3]->rasterLock = rasterLock;
|
||||
engine->driver[PLATFORM_GL3]->rasterUnlock = rasterUnlock;
|
||||
engine->driver[PLATFORM_GL3]->rasterNumLevels = rasterNumLevels;
|
||||
engine->driver[PLATFORM_GL3]->rasterFromImage = rasterFromImage;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
|
|
@ -10,10 +10,13 @@
|
|||
#include "../rwengine.h"
|
||||
#ifdef RW_OPENGL
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "rwgl3.h"
|
||||
#include "rwgl3shader.h"
|
||||
#include "rwgl3impl.h"
|
||||
|
||||
#define PLUGIN_ID 0
|
||||
|
||||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
|
@ -77,7 +80,9 @@ static uint32 srcblend, destblend;
|
|||
static uint32 zwrite;
|
||||
static uint32 ztest;
|
||||
|
||||
uint32 blendMap[] = {
|
||||
static int32 activeTexture;
|
||||
|
||||
static uint32 blendMap[] = {
|
||||
GL_ZERO,
|
||||
GL_ONE,
|
||||
GL_SRC_COLOR,
|
||||
|
@ -91,18 +96,26 @@ uint32 blendMap[] = {
|
|||
GL_SRC_ALPHA_SATURATE,
|
||||
};
|
||||
|
||||
void
|
||||
static void
|
||||
setVertexAlpha(bool32 enable)
|
||||
{
|
||||
if(vertexAlpha != enable){
|
||||
vertexAlpha = enable;
|
||||
if(!textureAlpha){
|
||||
if(enable)
|
||||
glEnable(GL_BLEND);
|
||||
else
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setRenderState(int32 state, uint32 value)
|
||||
{
|
||||
switch(state){
|
||||
case VERTEXALPHA:
|
||||
if(vertexAlpha != value){
|
||||
vertexAlpha = value;
|
||||
if(vertexAlpha)
|
||||
glEnable(GL_BLEND);
|
||||
else if(!textureAlpha)
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
setVertexAlpha(value);
|
||||
break;
|
||||
case SRCBLEND:
|
||||
if(srcblend != value){
|
||||
|
@ -158,7 +171,7 @@ setRenderState(int32 state, uint32 value)
|
|||
}
|
||||
}
|
||||
|
||||
uint32
|
||||
static uint32
|
||||
getRenderState(int32 state)
|
||||
{
|
||||
RGBA rgba;
|
||||
|
@ -182,15 +195,15 @@ getRenderState(int32 state)
|
|||
case ALPHATESTFUNC:
|
||||
return uniformState.alphaFunc;
|
||||
case ALPHATESTREF:
|
||||
return uniformState.alphaRef*255.0f;
|
||||
return (uint32)(uniformState.alphaRef*255.0f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
resetRenderState(void)
|
||||
{
|
||||
uniformState.alphaFunc = ALPHAGREATERTHAN;
|
||||
uniformState.alphaFunc = ALPHAGREATEREQUAL;
|
||||
uniformState.alphaRef = 10.0f/255.0f;
|
||||
uniformState.fogEnable = 0;
|
||||
uniformState.fogStart = 0.0f;
|
||||
|
@ -254,7 +267,7 @@ setLight(int32 n, Light *light)
|
|||
l->direction = m->at;
|
||||
}
|
||||
// light has position
|
||||
l->w = light->getType() >= Light::POINT ? 1.0f : 0.0;
|
||||
l->w = light->getType() >= Light::POINT ? 1.0f : 0.0f;
|
||||
l->color = light->color;
|
||||
l->radius = light->radius;
|
||||
l->minusCosAngle = light->minusCosAngle;
|
||||
|
@ -275,11 +288,20 @@ setViewMatrix(float32 *mat)
|
|||
sceneDirty = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
setActiveTexture(int32 n)
|
||||
{
|
||||
if(activeTexture != n){
|
||||
activeTexture = n;
|
||||
glActiveTexture(n);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setTexture(int32 n, Texture *tex)
|
||||
{
|
||||
bool32 alpha;
|
||||
glActiveTexture(GL_TEXTURE0+n);
|
||||
setActiveTexture(GL_TEXTURE0+n);
|
||||
if(tex == nil || tex->raster->platform != PLATFORM_GL3 ||
|
||||
tex->raster->width == 0){
|
||||
glBindTexture(GL_TEXTURE_2D, whitetex);
|
||||
|
@ -291,12 +313,16 @@ setTexture(int32 n, Texture *tex)
|
|||
alpha = natras->hasAlpha;
|
||||
}
|
||||
|
||||
if(textureAlpha != alpha){
|
||||
textureAlpha = alpha;
|
||||
if(textureAlpha)
|
||||
glEnable(GL_BLEND);
|
||||
else if(!vertexAlpha)
|
||||
glDisable(GL_BLEND);
|
||||
if(n == 0){
|
||||
if(alpha != textureAlpha){
|
||||
textureAlpha = alpha;
|
||||
if(!vertexAlpha){
|
||||
if(alpha)
|
||||
glEnable(GL_BLEND);
|
||||
else
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,7 +349,7 @@ flushCache(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
clearCamera(Camera *cam, RGBA *col, uint32 mode)
|
||||
{
|
||||
RGBAf colf;
|
||||
|
@ -339,7 +365,16 @@ clearCamera(Camera *cam, RGBA *col, uint32 mode)
|
|||
glClear(mask);
|
||||
}
|
||||
|
||||
void
|
||||
static GLFWwindow *glfwwindow;
|
||||
|
||||
static void
|
||||
showRaster(Raster *raster)
|
||||
{
|
||||
// TODO: do this properly!
|
||||
glfwSwapBuffers(glfwwindow);
|
||||
}
|
||||
|
||||
static void
|
||||
beginUpdate(Camera *cam)
|
||||
{
|
||||
float view[16], proj[16];
|
||||
|
@ -410,17 +445,62 @@ beginUpdate(Camera *cam)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
initializeRender(void)
|
||||
static int
|
||||
startGLFW(EngineStartParams *startparams)
|
||||
{
|
||||
engine->beginUpdate = beginUpdate;
|
||||
engine->clearCamera = clearCamera;
|
||||
engine->setRenderState = setRenderState;
|
||||
engine->getRenderState = getRenderState;
|
||||
engine->im2DRenderIndexedPrimitive = im2DRenderIndexedPrimitive;
|
||||
engine->zNear = -1.0f;
|
||||
engine->zFar = 1.0f;
|
||||
GLenum status;
|
||||
GLFWwindow *win;
|
||||
|
||||
/* Init GLFW */
|
||||
if(!glfwInit()){
|
||||
RWERROR((ERR_GENERAL, "glfwInit() failed"));
|
||||
return 0;
|
||||
}
|
||||
glfwWindowHint(GLFW_SAMPLES, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
win = glfwCreateWindow(startparams->width, startparams->height, startparams->windowtitle, 0, 0);
|
||||
if(win == nil){
|
||||
RWERROR((ERR_GENERAL, "glfwCreateWindow() failed"));
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
glfwMakeContextCurrent(win);
|
||||
|
||||
/* Init GLEW */
|
||||
glewExperimental = GL_TRUE;
|
||||
status = glewInit();
|
||||
if(status != GLEW_OK){
|
||||
RWERROR((ERR_GENERAL, glewGetErrorString(status)));
|
||||
glfwDestroyWindow(win);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
if(!GLEW_VERSION_3_3){
|
||||
RWERROR((ERR_GENERAL, "OpenGL 3.3 needed"));
|
||||
glfwDestroyWindow(win);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
glfwwindow = win;
|
||||
*startparams->window = win;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
stopGLFW(void)
|
||||
{
|
||||
glfwDestroyWindow(glfwwindow);
|
||||
glfwTerminate();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
initOpenGL(void)
|
||||
{
|
||||
#include "shaders/simple_gl3.inc"
|
||||
simpleShader = Shader::fromStrings(simple_vert_src, simple_frag_src);
|
||||
|
||||
|
@ -438,7 +518,6 @@ initializeRender(void)
|
|||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
|
||||
glGenBuffers(1, &ubo_scene);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, ubo_scene);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Scene"), ubo_scene);
|
||||
|
@ -446,7 +525,6 @@ initializeRender(void)
|
|||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
|
||||
glGenBuffers(1, &ubo_object);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, ubo_object);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, gl3::findBlock("Object"), ubo_object);
|
||||
|
@ -454,7 +532,6 @@ initializeRender(void)
|
|||
GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
|
||||
byte whitepixel[4] = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||
glGenTextures(1, &whitetex);
|
||||
glBindTexture(GL_TEXTURE_2D, whitetex);
|
||||
|
@ -464,7 +541,35 @@ initializeRender(void)
|
|||
0, GL_RGBA, GL_UNSIGNED_BYTE, &whitepixel);
|
||||
|
||||
im2DInit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
deviceSystem(DeviceReq req, void *arg0)
|
||||
{
|
||||
switch(req){
|
||||
case DEVICESTART:
|
||||
return startGLFW((EngineStartParams*)arg0);
|
||||
case DEVICEINIT:
|
||||
return initOpenGL();
|
||||
case DEVICESTOP:
|
||||
return stopGLFW();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Device renderdevice = {
|
||||
-1.0f, 1.0f,
|
||||
gl3::beginUpdate,
|
||||
null::endUpdate,
|
||||
gl3::clearCamera,
|
||||
gl3::showRaster,
|
||||
gl3::setRenderState,
|
||||
gl3::getRenderState,
|
||||
gl3::im2DRenderIndexedPrimitive,
|
||||
gl3::deviceSystem
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ void
|
|||
lightingCB(void)
|
||||
{
|
||||
World *world;
|
||||
RGBAf ambLight = (RGBAf){0.0, 0.0, 0.0, 1.0};
|
||||
RGBAf ambLight = { 0.0, 0.0, 0.0, 1.0 };
|
||||
int n = 0;
|
||||
|
||||
world = (World*)engine->currentWorld;
|
||||
|
@ -84,9 +84,6 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
InstanceData *inst = header->inst;
|
||||
int32 n = header->numMeshes;
|
||||
|
||||
// rw::setRenderState(ALPHATESTFUNC, 1);
|
||||
// rw::setRenderState(ALPHATESTREF, 50);
|
||||
|
||||
simpleShader->use();
|
||||
|
||||
while(n--){
|
||||
|
|
|
@ -189,8 +189,10 @@ Shader::fromFiles(const char *vspath, const char *fspath)
|
|||
void
|
||||
Shader::use(void)
|
||||
{
|
||||
glUseProgram(this->program);
|
||||
currentShader = this;
|
||||
if(currentShader != this){
|
||||
glUseProgram(this->program);
|
||||
currentShader = this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
#ifdef RW_GL3
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#endif
|
||||
|
||||
namespace rw {
|
||||
|
||||
#ifdef RW_GL3
|
||||
struct EngineStartParams
|
||||
{
|
||||
GLFWwindow **window;
|
||||
int width, height;
|
||||
const char *windowtitle;
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace gl3 {
|
||||
|
||||
void initializePlatform(void);
|
||||
void initializeRender(void);
|
||||
|
||||
extern Device renderdevice;
|
||||
|
||||
// arguments to glVertexAttribPointer basically
|
||||
struct AttribDesc
|
||||
|
|
|
@ -10,6 +10,6 @@ out vec4 color;
|
|||
void
|
||||
main(void)
|
||||
{
|
||||
color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));
|
||||
color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ const char *im2d_frag_src =
|
|||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));\n"
|
||||
" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n"
|
||||
"}\n"
|
||||
|
||||
;
|
||||
|
|
|
@ -17,7 +17,7 @@ out vec4 color;
|
|||
void
|
||||
main(void)
|
||||
{
|
||||
color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));
|
||||
color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));
|
||||
switch(u_alphaTest){
|
||||
default:
|
||||
case 0: break;
|
||||
|
|
|
@ -78,7 +78,7 @@ const char *matfx_env_frag_src =
|
|||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));\n"
|
||||
" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n"
|
||||
" switch(u_alphaTest){\n"
|
||||
" default:\n"
|
||||
" case 0: break;\n"
|
||||
|
|
|
@ -22,7 +22,7 @@ out vec4 color;
|
|||
void
|
||||
main(void)
|
||||
{
|
||||
color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));
|
||||
color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));
|
||||
if(u_fogEnable != 0)
|
||||
color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);
|
||||
switch(u_alphaTest){
|
||||
|
|
|
@ -95,7 +95,7 @@ const char *simple_frag_src =
|
|||
"void\n"
|
||||
"main(void)\n"
|
||||
"{\n"
|
||||
" color = v_color*texture2D(tex, vec2(v_tex0.x, v_tex0.y));\n"
|
||||
" color = v_color*texture(tex, vec2(v_tex0.x, v_tex0.y));\n"
|
||||
" if(u_fogEnable != 0)\n"
|
||||
" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n"
|
||||
" switch(u_alphaTest){\n"
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace wdgl {
|
|||
void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
driver[PLATFORM_WDGL]->defaultPipeline = makeDefaultPipeline();
|
||||
engine->driver[PLATFORM_WDGL]->defaultPipeline = makeDefaultPipeline();
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -820,7 +820,7 @@ Texture::upload(void)
|
|||
switch(r->format & 0xF00){
|
||||
case Raster::C8888:
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, r->width, r->height,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, r->texels);
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, r->pixels);
|
||||
break;
|
||||
default:
|
||||
printf("unsupported raster format: %x\n", r->format);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "rwengine.h"
|
||||
#include "rwanim.h"
|
||||
#include "rwplugins.h"
|
||||
#include "ps2/rwps2.h"
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
|
||||
namespace rw {
|
||||
|
||||
PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil };
|
||||
PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil };
|
||||
PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil };
|
||||
|
||||
//
|
||||
// TexDictionary
|
||||
//
|
||||
|
@ -904,6 +908,7 @@ Image::getFilename(const char *name)
|
|||
Raster*
|
||||
Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platform)
|
||||
{
|
||||
// TODO: pass arguments through to the driver and create the raster there
|
||||
Raster *raster = (Raster*)malloc(s_plglist.size);
|
||||
assert(raster != nil);
|
||||
raster->platform = platform ? platform : rw::platform;
|
||||
|
@ -913,11 +918,11 @@ Raster::create(int32 width, int32 height, int32 depth, int32 format, int32 platf
|
|||
raster->width = width;
|
||||
raster->height = height;
|
||||
raster->depth = depth;
|
||||
raster->texels = raster->palette = nil;
|
||||
raster->pixels = raster->palette = nil;
|
||||
s_plglist.construct(raster);
|
||||
|
||||
// printf("%d %d %d %d\n", raster->type, raster->width, raster->height, raster->depth);
|
||||
driver[raster->platform]->rasterCreate(raster);
|
||||
engine->driver[raster->platform]->rasterCreate(raster);
|
||||
return raster;
|
||||
}
|
||||
|
||||
|
@ -933,19 +938,19 @@ Raster::destroy(void)
|
|||
uint8*
|
||||
Raster::lock(int32 level)
|
||||
{
|
||||
return driver[this->platform]->rasterLock(this, level);
|
||||
return engine->driver[this->platform]->rasterLock(this, level);
|
||||
}
|
||||
|
||||
void
|
||||
Raster::unlock(int32 level)
|
||||
{
|
||||
driver[this->platform]->rasterUnlock(this, level);
|
||||
engine->driver[this->platform]->rasterUnlock(this, level);
|
||||
}
|
||||
|
||||
int32
|
||||
Raster::getNumLevels(void)
|
||||
{
|
||||
return driver[this->platform]->rasterNumLevels(this);
|
||||
return engine->driver[this->platform]->rasterNumLevels(this);
|
||||
}
|
||||
|
||||
int32
|
||||
|
@ -964,14 +969,14 @@ Raster::createFromImage(Image *image, int32 platform)
|
|||
Raster *raster = Raster::create(image->width, image->height,
|
||||
image->depth, TEXTURE | DONTALLOCATE,
|
||||
platform);
|
||||
driver[raster->platform]->rasterFromImage(raster, image);
|
||||
engine->driver[raster->platform]->rasterFromImage(raster, image);
|
||||
return raster;
|
||||
}
|
||||
|
||||
Image*
|
||||
Raster::toImage(void)
|
||||
{
|
||||
return driver[this->platform]->rasterToImage(this);
|
||||
return engine->driver[this->platform]->rasterToImage(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
namespace rw {
|
||||
|
||||
PluginList Light::s_plglist = { sizeof(Light), sizeof(Light), nil, nil };
|
||||
|
||||
static void
|
||||
lightSync(ObjectWithFrame*)
|
||||
{
|
||||
|
|
|
@ -145,7 +145,7 @@ MatFX::get(Material *m)
|
|||
return *PLUGINOFFSET(MatFX*, m, matFXGlobals.materialOffset);
|
||||
}
|
||||
|
||||
uint32
|
||||
int32
|
||||
MatFX::getEffectIndex(uint32 type)
|
||||
{
|
||||
for(int i = 0; i < 2; i++)
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "rwplg.h"
|
||||
#include "rwpipeline.h"
|
||||
#include "rwobjects.h"
|
||||
#include "ps2/rwps2.h"
|
||||
|
||||
#define COLOR_ARGB(a,r,g,b) \
|
||||
((uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwanim.h"
|
||||
#include "../rwplugins.h"
|
||||
#include "rwps2.h"
|
||||
|
|
|
@ -24,13 +24,13 @@ namespace ps2 {
|
|||
void*
|
||||
driverOpen(void *o, int32, int32)
|
||||
{
|
||||
driver[PLATFORM_PS2]->defaultPipeline = makeDefaultPipeline();
|
||||
engine->driver[PLATFORM_PS2]->defaultPipeline = makeDefaultPipeline();
|
||||
|
||||
driver[PLATFORM_PS2]->rasterNativeOffset = nativeRasterOffset;
|
||||
driver[PLATFORM_PS2]->rasterCreate = rasterCreate;
|
||||
driver[PLATFORM_PS2]->rasterLock = rasterLock;
|
||||
driver[PLATFORM_PS2]->rasterUnlock = rasterUnlock;
|
||||
driver[PLATFORM_PS2]->rasterNumLevels = rasterNumLevels;
|
||||
engine->driver[PLATFORM_PS2]->rasterNativeOffset = nativeRasterOffset;
|
||||
engine->driver[PLATFORM_PS2]->rasterCreate = rasterCreate;
|
||||
engine->driver[PLATFORM_PS2]->rasterLock = rasterLock;
|
||||
engine->driver[PLATFORM_PS2]->rasterUnlock = rasterUnlock;
|
||||
engine->driver[PLATFORM_PS2]->rasterNumLevels = rasterNumLevels;
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
|||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
@ -92,7 +92,6 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
|||
uint32 buf[2];
|
||||
stream->read(buf, 8);
|
||||
instance->dataSize = buf[0];
|
||||
instance->arePointersFixed = buf[1];
|
||||
// TODO: force alignment
|
||||
instance->data = new uint8[instance->dataSize];
|
||||
#ifdef RW_PS2
|
||||
|
@ -100,6 +99,10 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
|
|||
assert(a % 0x10 == 0);
|
||||
#endif
|
||||
stream->read(instance->data, instance->dataSize);
|
||||
#ifdef RW_PS2
|
||||
if(!buf[1])
|
||||
fixDmaOffsets(instance);
|
||||
#endif
|
||||
instance->material = geometry->meshHeader->mesh[i].material;
|
||||
// sizedebug(instance);
|
||||
}
|
||||
|
@ -118,13 +121,15 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
|
|||
InstanceDataHeader *header = (InstanceDataHeader*)geometry->instData;
|
||||
for(uint32 i = 0; i < header->numMeshes; i++){
|
||||
InstanceData *instance = &header->instanceMeshes[i];
|
||||
if(instance->arePointersFixed == 2)
|
||||
unfixDmaOffsets(instance);
|
||||
uint32 buf[2];
|
||||
buf[0] = instance->dataSize;
|
||||
buf[1] = instance->arePointersFixed;
|
||||
buf[1] = unfixDmaOffsets(instance);
|
||||
stream->write(buf, 8);
|
||||
stream->write(instance->data, instance->dataSize);
|
||||
#ifdef RW_PS2
|
||||
if(!buf[1])
|
||||
fixDmaOffsets(instance);
|
||||
#endif
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
@ -157,13 +162,11 @@ registerNativeDataPlugin(void)
|
|||
getSizeNativeData);
|
||||
}
|
||||
|
||||
// Patch DMA ref ADDR fields to point to the actual data.
|
||||
#ifdef RW_PS2
|
||||
void
|
||||
fixDmaOffsets(InstanceData *inst)
|
||||
{
|
||||
if(inst->arePointersFixed)
|
||||
return;
|
||||
|
||||
uint32 base = (uint32)inst->data;
|
||||
uint32 *tag = (uint32*)inst->data;
|
||||
for(;;){
|
||||
|
@ -184,7 +187,6 @@ fixDmaOffsets(InstanceData *inst)
|
|||
// DMAret
|
||||
case 0x60000000:
|
||||
// we're done
|
||||
inst->arePointersFixed = 2;
|
||||
return;
|
||||
|
||||
default:
|
||||
|
@ -195,15 +197,17 @@ fixDmaOffsets(InstanceData *inst)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
// Patch DMA ref ADDR fields to qword offsets and return whether
|
||||
// no ref tags were found.
|
||||
// Only under RW_PS2 are the addresses actually patched but we need
|
||||
// the return value for streaming out.
|
||||
bool32
|
||||
unfixDmaOffsets(InstanceData *inst)
|
||||
{
|
||||
(void)inst;
|
||||
bool32 norefs = 1;
|
||||
#ifdef RW_PS2
|
||||
if(inst->arePointersFixed != 2)
|
||||
return;
|
||||
|
||||
uint32 base = (uint32)inst->data;
|
||||
#endif
|
||||
uint32 *tag = (uint32*)inst->data;
|
||||
for(;;){
|
||||
switch(tag[0]&0x70000000){
|
||||
|
@ -215,23 +219,23 @@ unfixDmaOffsets(InstanceData *inst)
|
|||
|
||||
// DMAref
|
||||
case 0x30000000:
|
||||
norefs = 0;
|
||||
// unfix address and jump to next
|
||||
#ifdef RW_PS2
|
||||
tag[1] = (tag[1] - base)>>4;
|
||||
#endif
|
||||
tag += 4;
|
||||
break;
|
||||
|
||||
// DMAret
|
||||
case 0x60000000:
|
||||
// we're done
|
||||
inst->arePointersFixed = 0;
|
||||
return;
|
||||
return norefs;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "error: unknown DMAtag %X\n", tag[0]);
|
||||
return;
|
||||
return norefs;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Pipeline
|
||||
|
@ -586,7 +590,6 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
|||
InstMeshInfo im = getInstMeshInfo(this, g, m);
|
||||
|
||||
inst->dataSize = (im.size+im.size2)<<4;
|
||||
inst->arePointersFixed = im.numBrokenAttribs == 0;
|
||||
// TODO: force alignment
|
||||
inst->data = new uint8[inst->dataSize];
|
||||
|
||||
|
@ -685,6 +688,10 @@ MatPipeline::instance(Geometry *g, InstanceData *inst, Mesh *m)
|
|||
|
||||
if(this->instanceCB)
|
||||
this->instanceCB(this, g, m, datap);
|
||||
#ifdef RW_PS2
|
||||
if(im.numBrokenAttribs)
|
||||
fixDmaOffsets(inst);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8*
|
||||
|
@ -766,6 +773,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
|||
geo->flags |= Geometry::NATIVE;
|
||||
}
|
||||
|
||||
/*
|
||||
static void
|
||||
printVertCounts(InstanceData *inst, int flag)
|
||||
{
|
||||
|
@ -794,6 +802,7 @@ printVertCounts(InstanceData *inst, int flag)
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void
|
||||
objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
|
||||
|
@ -1241,6 +1250,7 @@ registerADCPlugin(void)
|
|||
}
|
||||
|
||||
// misc stuff
|
||||
/*
|
||||
|
||||
void
|
||||
printDMA(InstanceData *inst)
|
||||
|
@ -1300,6 +1310,7 @@ sizedebug(InstanceData *inst)
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
#ifdef RW_PS2
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include "../rwbase.h"
|
||||
#include "../rwerror.h"
|
||||
#include "../rwplg.h"
|
||||
#include "../rwpipeline.h"
|
||||
#include "../rwobjects.h"
|
||||
#include "../rwengine.h"
|
||||
#include "../rwanim.h"
|
||||
#include "../rwplugins.h"
|
||||
#include "rwps2.h"
|
||||
#include "rwps2plg.h"
|
||||
|
||||
#include "rwps2impl.h"
|
||||
|
||||
#define PLUGIN_ID 2
|
||||
|
||||
namespace rw {
|
||||
namespace ps2 {
|
||||
|
||||
Device renderdevice = {
|
||||
16777215.0f, 0.0f,
|
||||
null::beginUpdate,
|
||||
null::endUpdate,
|
||||
null::clearCamera,
|
||||
null::showRaster,
|
||||
null::setRenderState,
|
||||
null::getRenderState,
|
||||
null::im2DRenderIndexedPrimitive,
|
||||
null::deviceSystem
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -74,7 +74,7 @@ readNativeSkin(Stream *stream, int32, void *object, int32 offset)
|
|||
Geometry *geometry = (Geometry*)object;
|
||||
uint32 platform;
|
||||
if(!findChunk(stream, ID_STRUCT, nil, nil)){
|
||||
RWERROR((ERR_CHUNK, "STRUCT"))
|
||||
RWERROR((ERR_CHUNK, "STRUCT"));
|
||||
return nil;
|
||||
}
|
||||
platform = stream->readU32();
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
namespace rw {
|
||||
|
||||
#ifdef RW_PS2
|
||||
struct EngineStartParams
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace ps2 {
|
||||
|
||||
void initializePlatform(void);
|
||||
|
||||
extern Device renderdevice;
|
||||
|
||||
struct InstanceData
|
||||
{
|
||||
// 0 - addresses in ref tags need fixing
|
||||
// 1 - no ref tags, so no fixing
|
||||
// set by the program:
|
||||
// 2 - ref tags are fixed, need to unfix before stream write
|
||||
uint32 arePointersFixed;
|
||||
uint32 dataSize;
|
||||
uint8 *data;
|
||||
Material *material;
|
||||
|
@ -57,10 +61,8 @@ void registerNativeDataPlugin(void);
|
|||
void printDMA(InstanceData *inst);
|
||||
void sizedebug(InstanceData *inst);
|
||||
|
||||
// only RW_PS2
|
||||
void fixDmaOffsets(InstanceData *inst);
|
||||
void unfixDmaOffsets(InstanceData *inst);
|
||||
//
|
||||
void fixDmaOffsets(InstanceData *inst); // only RW_PS2
|
||||
int32 unfixDmaOffsets(InstanceData *inst);
|
||||
|
||||
struct PipeAttribute
|
||||
{
|
||||
|
@ -181,22 +183,30 @@ void registerPluginPDSPipes(void);
|
|||
struct Ps2Raster
|
||||
{
|
||||
enum Flags {
|
||||
HASGIFPACKETS = 0x1,
|
||||
SWIZZLED8 = 0x2,
|
||||
SWIZZLED4 = 0x4,
|
||||
NEWSTYLE = 0x1, // has GIF tags and transfer DMA chain
|
||||
SWIZZLED8 = 0x2,
|
||||
SWIZZLED4 = 0x4,
|
||||
};
|
||||
struct PixelPtr {
|
||||
// RW has pixels as second element but we don't want this struct
|
||||
// to be longer than 16 bytes
|
||||
uint8 *pixels;
|
||||
// palette can be allocated in last level, in that case numTransfers is
|
||||
// one less than numTotalTransfers.
|
||||
int32 numTransfers;
|
||||
int32 numTotalTransfers;
|
||||
};
|
||||
|
||||
uint32 tex0[2];
|
||||
uint32 paletteOffset; // from beginning of GS data;
|
||||
// in words/64
|
||||
uint64 tex0;
|
||||
uint32 paletteBase; // block address from beginning of GS data (words/64)
|
||||
uint16 kl;
|
||||
uint8 tex1low; // MXL and LCM of TEX1
|
||||
uint8 unk2;
|
||||
uint32 miptbp1[2];
|
||||
uint32 miptbp2[2];
|
||||
uint32 texelSize;
|
||||
uint32 paletteSize;
|
||||
uint32 gsSize;
|
||||
uint64 miptbp1;
|
||||
uint64 miptbp2;
|
||||
uint32 pixelSize; // in bytes
|
||||
uint32 paletteSize; // in bytes
|
||||
uint32 totalSize; // total size of texture on GS in words
|
||||
int8 flags;
|
||||
|
||||
uint8 *data; //tmp
|
||||
|
|
|
@ -231,6 +231,7 @@ struct Matrix
|
|||
Matrix *rotate(const Quat &q, CombineOp op);
|
||||
Matrix *translate(V3d *translation, CombineOp op);
|
||||
Matrix *scale(V3d *scl, CombineOp op);
|
||||
Matrix *transform(Matrix *mat, CombineOp op);
|
||||
void lookAt(const V3d &dir, const V3d &up);
|
||||
|
||||
// helper functions. consider private
|
||||
|
|
|
@ -22,9 +22,9 @@ enum RenderState
|
|||
|
||||
enum AlphaTestFunc
|
||||
{
|
||||
ALPHANEVER = 0,
|
||||
ALPHALESS,
|
||||
ALPHAGREATERTHAN
|
||||
ALPHAALWAYS = 0,
|
||||
ALPHAGREATEREQUAL,
|
||||
ALPHALESS
|
||||
};
|
||||
|
||||
enum BlendFunction
|
||||
|
@ -43,37 +43,35 @@ enum BlendFunction
|
|||
// TODO: add more perhaps
|
||||
};
|
||||
|
||||
// This is for platform independent things and the render device (of which
|
||||
// there can only ever be one).
|
||||
// TODO: move more stuff into this
|
||||
struct Engine
|
||||
enum DeviceReq
|
||||
{
|
||||
void *currentCamera;
|
||||
void *currentWorld;
|
||||
Texture *imtexture;
|
||||
// Device/Context creation
|
||||
DEVICESTART,
|
||||
// Device initialization before Engine/Driver plugins are opened
|
||||
DEVICEINIT,
|
||||
// Device/Context shutdown
|
||||
DEVICESTOP,
|
||||
};
|
||||
|
||||
TexDictionary *currentTexDictionary;
|
||||
bool32 loadTextures; // load textures from files
|
||||
bool32 makeDummies; // create dummy textures to store just names
|
||||
typedef int DeviceSystem(DeviceReq req, void *arg0);
|
||||
|
||||
|
||||
// Device
|
||||
// This is for the render device, we only have one
|
||||
struct Device
|
||||
{
|
||||
float32 zNear, zFar;
|
||||
void (*beginUpdate)(Camera*);
|
||||
void (*endUpdate)(Camera*);
|
||||
void (*clearCamera)(Camera*, RGBA *col, uint32 mode);
|
||||
void (*showRaster)(Raster *raster);
|
||||
void (*setRenderState)(int32 state, uint32 value);
|
||||
uint32 (*getRenderState)(int32 state);
|
||||
void (*im2DRenderIndexedPrimitive)(PrimitiveType,
|
||||
void*, int32, void*, int32);
|
||||
|
||||
static void init(void);
|
||||
DeviceSystem *system;
|
||||
};
|
||||
|
||||
extern Engine *engine;
|
||||
|
||||
// This is for platform driver implementations which have to be available
|
||||
// regardless of the render device.
|
||||
// This is for platform-dependent but portable things
|
||||
// so the engine has one for every platform
|
||||
struct Driver
|
||||
{
|
||||
ObjPipeline *defaultPipeline;
|
||||
|
@ -87,7 +85,6 @@ struct Driver
|
|||
Image *(*rasterToImage)(Raster*);
|
||||
|
||||
static PluginList s_plglist[NUM_PLATFORMS];
|
||||
static void open(void);
|
||||
static int32 registerPlugin(int32 platform, int32 size, uint32 id,
|
||||
Constructor ctor, Destructor dtor){
|
||||
return s_plglist[platform].registerPlugin(size, id,
|
||||
|
@ -95,19 +92,55 @@ struct Driver
|
|||
}
|
||||
};
|
||||
|
||||
extern Driver *driver[NUM_PLATFORMS];
|
||||
#define DRIVER driver[rw::platform]
|
||||
struct EngineStartParams;
|
||||
|
||||
// This is for platform independent things
|
||||
// TODO: move more stuff into this
|
||||
// TODO: make this have plugins and allocate in Engine::open
|
||||
struct Engine
|
||||
{
|
||||
enum State {
|
||||
Dead = 0,
|
||||
Initialized,
|
||||
Opened,
|
||||
Started
|
||||
};
|
||||
void *currentCamera;
|
||||
void *currentWorld;
|
||||
Texture *imtexture;
|
||||
|
||||
TexDictionary *currentTexDictionary;
|
||||
// load textures from files
|
||||
bool32 loadTextures;
|
||||
// create dummy textures to store just names
|
||||
bool32 makeDummies;
|
||||
// Dynamically allocated because of plugins
|
||||
Driver *driver[NUM_PLATFORMS];
|
||||
Device device;
|
||||
|
||||
static State state;
|
||||
|
||||
static bool32 init(void);
|
||||
static bool32 open(void);
|
||||
static bool32 start(EngineStartParams*);
|
||||
static void term(void);
|
||||
static void close(void);
|
||||
static void stop(void);
|
||||
};
|
||||
|
||||
extern Engine *engine;
|
||||
|
||||
inline void SetRenderState(int32 state, uint32 value){
|
||||
engine->setRenderState(state, value); }
|
||||
engine->device.setRenderState(state, value); }
|
||||
|
||||
inline uint32 GetRenderState(int32 state){
|
||||
return engine->getRenderState(state); }
|
||||
return engine->device.getRenderState(state); }
|
||||
|
||||
namespace null {
|
||||
void beginUpdate(Camera*);
|
||||
void endUpdate(Camera*);
|
||||
void clearCamera(Camera*, RGBA *col, uint32 mode);
|
||||
void showRaster(Raster*);
|
||||
|
||||
void setRenderState(int32 state, uint32 value);
|
||||
uint32 getRenderState(int32 state);
|
||||
|
@ -121,6 +154,10 @@ namespace null {
|
|||
|
||||
void im2DRenderIndexedPrimitive(PrimitiveType,
|
||||
void*, int32, void*, int32);
|
||||
|
||||
int deviceSystem(DeviceReq req, void*);
|
||||
|
||||
extern Device renderdevice;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,6 @@ char *dbgsprint(int32 code, ...);
|
|||
fprintf(stderr, "%s:%d: ", __FILE__, __LINE__); \
|
||||
fprintf(stderr, "%s\n", rw::dbgsprint ecode); \
|
||||
rw::setError(&_e); \
|
||||
}while(0);
|
||||
}while(0)
|
||||
|
||||
}
|
||||
|
|
|
@ -82,8 +82,9 @@ struct Object
|
|||
}
|
||||
};
|
||||
|
||||
struct Frame : PluginBase<Frame>
|
||||
struct Frame
|
||||
{
|
||||
PLUGINBASE
|
||||
typedef Frame *(*Callback)(Frame *f, void *data);
|
||||
enum { ID = 0 };
|
||||
enum { // private flags
|
||||
|
@ -125,7 +126,8 @@ struct Frame : PluginBase<Frame>
|
|||
Matrix *getLTM(void);
|
||||
void rotate(V3d *axis, float32 angle, CombineOp op);
|
||||
void translate(V3d *trans, CombineOp op);
|
||||
void scale(V3d *trans, CombineOp op);
|
||||
void scale(V3d *scale, CombineOp op);
|
||||
void transform(Matrix *mat, CombineOp op);
|
||||
void updateObjects(void);
|
||||
|
||||
|
||||
|
@ -214,17 +216,26 @@ struct RasterLevels
|
|||
} levels[1]; // 0 is illegal :/
|
||||
};
|
||||
|
||||
struct Raster : PluginBase<Raster>
|
||||
struct Raster
|
||||
{
|
||||
PLUGINBASE
|
||||
int32 platform;
|
||||
|
||||
int32 type; // hardly used
|
||||
// TODO: use bytes
|
||||
int32 type;
|
||||
int32 flags;
|
||||
int32 format;
|
||||
int32 width, height, depth;
|
||||
int32 stride;
|
||||
uint8 *texels;
|
||||
uint8 *pixels;
|
||||
uint8 *palette;
|
||||
uint8 *originalPixels;
|
||||
// TODO: use them (for locking mainly)
|
||||
int32 originalWidth;
|
||||
int32 originalHeight;
|
||||
int32 originalStride;
|
||||
// TODO:
|
||||
// parent raster and offset
|
||||
|
||||
static Raster *create(int32 width, int32 height, int32 depth,
|
||||
int32 format, int32 platform = 0);
|
||||
|
@ -267,8 +278,9 @@ struct Raster : PluginBase<Raster>
|
|||
|
||||
struct TexDictionary;
|
||||
|
||||
struct Texture : PluginBase<Texture>
|
||||
struct Texture
|
||||
{
|
||||
PLUGINBASE
|
||||
Raster *raster;
|
||||
TexDictionary *dict;
|
||||
LLLink inDict;
|
||||
|
@ -316,8 +328,9 @@ struct SurfaceProperties
|
|||
float32 diffuse;
|
||||
};
|
||||
|
||||
struct Material : PluginBase<Material>
|
||||
struct Material
|
||||
{
|
||||
PLUGINBASE
|
||||
Texture *texture;
|
||||
RGBA color;
|
||||
SurfaceProperties surfaceProps;
|
||||
|
@ -390,8 +403,9 @@ struct MaterialList
|
|||
uint32 streamGetSize(void);
|
||||
};
|
||||
|
||||
struct Geometry : PluginBase<Geometry>
|
||||
struct Geometry
|
||||
{
|
||||
PLUGINBASE
|
||||
enum { ID = 8 };
|
||||
Object object;
|
||||
uint32 flags;
|
||||
|
@ -452,8 +466,9 @@ void registerNativeDataPlugin(void);
|
|||
struct Clump;
|
||||
struct World;
|
||||
|
||||
struct Atomic : PluginBase<Atomic>
|
||||
struct Atomic
|
||||
{
|
||||
PLUGINBASE
|
||||
typedef void (*RenderCB)(Atomic *atomic);
|
||||
enum { ID = 1 };
|
||||
enum {
|
||||
|
@ -508,8 +523,9 @@ struct Atomic : PluginBase<Atomic>
|
|||
|
||||
void registerAtomicRightsPlugin(void);
|
||||
|
||||
struct Light : PluginBase<Light>
|
||||
struct Light
|
||||
{
|
||||
PLUGINBASE
|
||||
enum { ID = 3 };
|
||||
ObjectWithFrame object;
|
||||
float32 radius;
|
||||
|
@ -567,8 +583,9 @@ struct FrustumPlane
|
|||
uint8 closestZ;
|
||||
};
|
||||
|
||||
struct Camera : PluginBase<Camera>
|
||||
struct Camera
|
||||
{
|
||||
PLUGINBASE
|
||||
enum { ID = 4 };
|
||||
enum { PERSPECTIVE = 1, PARALLEL };
|
||||
enum { CLEARIMAGE = 0x1, CLEARZ = 0x2};
|
||||
|
@ -612,8 +629,12 @@ struct Camera : PluginBase<Camera>
|
|||
void beginUpdate(void) { this->beginUpdateCB(this); }
|
||||
void endUpdate(void) { this->endUpdateCB(this); }
|
||||
void clear(RGBA *col, uint32 mode);
|
||||
void showRaster(void);
|
||||
void setNearPlane(float32);
|
||||
void setFarPlane(float32);
|
||||
void setViewWindow(const V2d *window);
|
||||
void setViewOffset(const V2d *offset);
|
||||
void setProjection(int32 proj);
|
||||
int32 frustumTestSphere(Sphere *s);
|
||||
static Camera *streamRead(Stream *stream);
|
||||
bool streamWrite(Stream *stream);
|
||||
|
@ -623,8 +644,9 @@ struct Camera : PluginBase<Camera>
|
|||
void setFOV(float32 fov, float32 ratio);
|
||||
};
|
||||
|
||||
struct Clump : PluginBase<Clump>
|
||||
struct Clump
|
||||
{
|
||||
PLUGINBASE
|
||||
enum { ID = 2 };
|
||||
Object object;
|
||||
LinkList atomics;
|
||||
|
@ -662,8 +684,9 @@ struct Clump : PluginBase<Clump>
|
|||
};
|
||||
|
||||
// A bit of a stub right now
|
||||
struct World : PluginBase<World>
|
||||
struct World
|
||||
{
|
||||
PLUGINBASE
|
||||
enum { ID = 7 };
|
||||
Object object;
|
||||
LinkList lights; // these have positions (type >= 0x80)
|
||||
|
@ -674,8 +697,9 @@ struct World : PluginBase<World>
|
|||
void addCamera(Camera *cam);
|
||||
};
|
||||
|
||||
struct TexDictionary : PluginBase<TexDictionary>
|
||||
struct TexDictionary
|
||||
{
|
||||
PLUGINBASE
|
||||
enum { ID = 6 };
|
||||
Object object;
|
||||
LinkList textures;
|
||||
|
|
37
src/rwplg.h
37
src/rwplg.h
|
@ -49,27 +49,22 @@ struct PluginList
|
|||
int32 getPluginOffset(uint32 id);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct PluginBase
|
||||
{
|
||||
static PluginList s_plglist;
|
||||
#define PLUGINBASE \
|
||||
static PluginList s_plglist; \
|
||||
static int32 registerPlugin(int32 size, uint32 id, Constructor ctor, \
|
||||
Destructor dtor, CopyConstructor copy){ \
|
||||
return s_plglist.registerPlugin(size, id, ctor, dtor, copy); \
|
||||
} \
|
||||
static int32 registerPluginStream(uint32 id, StreamRead read, \
|
||||
StreamWrite write, StreamGetSize getSize){ \
|
||||
return s_plglist.registerStream(id, read, write, getSize); \
|
||||
} \
|
||||
static int32 setStreamRightsCallback(uint32 id, RightsCallback cb){ \
|
||||
return s_plglist.setStreamRightsCallback(id, cb); \
|
||||
} \
|
||||
static int32 getPluginOffset(uint32 id){ \
|
||||
return s_plglist.getPluginOffset(id); \
|
||||
}
|
||||
|
||||
static int32 registerPlugin(int32 size, uint32 id, Constructor ctor,
|
||||
Destructor dtor, CopyConstructor copy){
|
||||
return s_plglist.registerPlugin(size, id, ctor, dtor, copy);
|
||||
}
|
||||
static int32 registerPluginStream(uint32 id, StreamRead read,
|
||||
StreamWrite write, StreamGetSize getSize){
|
||||
return s_plglist.registerStream(id, read, write, getSize);
|
||||
}
|
||||
static int32 setStreamRightsCallback(uint32 id, RightsCallback cb){
|
||||
return s_plglist.setStreamRightsCallback(id, cb);
|
||||
}
|
||||
static int32 getPluginOffset(uint32 id){
|
||||
return s_plglist.getPluginOffset(id);
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
PluginList PluginBase<T>::s_plglist = { sizeof(T), sizeof(T), nil, nil };
|
||||
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ struct MatFX
|
|||
static void setEffects(Material *m, uint32 flags);
|
||||
static uint32 getEffects(Material *m);
|
||||
static MatFX *get(Material *m);
|
||||
uint32 getEffectIndex(uint32 type);
|
||||
int32 getEffectIndex(uint32 type);
|
||||
void setBumpTexture(Texture *t);
|
||||
void setBumpCoefficient(float32 coef);
|
||||
void setEnvTexture(Texture *t);
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
namespace rw {
|
||||
|
||||
PluginList World::s_plglist = { sizeof(World), sizeof(World), nil, nil };
|
||||
|
||||
World*
|
||||
World::create(void)
|
||||
{
|
||||
|
@ -33,14 +35,19 @@ World::addLight(Light *light)
|
|||
light->world = this;
|
||||
if(light->getType() < Light::POINT){
|
||||
this->directionalLights.append(&light->inWorld);
|
||||
}else
|
||||
}else{
|
||||
this->lights.append(&light->inWorld);
|
||||
if(light->getFrame())
|
||||
light->getFrame()->updateObjects();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
World::addCamera(Camera *cam)
|
||||
{
|
||||
cam->world = this;
|
||||
if(cam->getFrame())
|
||||
cam->getFrame()->updateObjects();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
#include <rw.h>
|
||||
|
||||
#define PI 3.14159265359f
|
||||
#include "camera.h"
|
||||
|
||||
using rw::Quat;
|
||||
using rw::V3d;
|
||||
|
||||
void
|
||||
Camera::update(void)
|
||||
{
|
||||
if(m_rwcam){
|
||||
m_rwcam->nearPlane = m_near;
|
||||
m_rwcam->farPlane = m_far;
|
||||
m_rwcam->setFOV(m_fov, m_aspectRatio);
|
||||
|
||||
rw::Frame *f = m_rwcam->getFrame();
|
||||
if(f){
|
||||
V3d forward = normalize(sub(m_target, m_position));
|
||||
V3d left = normalize(cross(m_up, forward));
|
||||
V3d nup = cross(forward, left);
|
||||
f->matrix.right = left; // lol
|
||||
f->matrix.up = nup;
|
||||
f->matrix.at = forward;
|
||||
f->matrix.pos = m_position;
|
||||
f->matrix.optimize();
|
||||
f->updateObjects();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Camera::setTarget(V3d target)
|
||||
{
|
||||
m_position = sub(m_position, sub(m_target, target));
|
||||
m_target = target;
|
||||
}
|
||||
|
||||
float
|
||||
Camera::getHeading(void)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
float a = atan2(dir.y, dir.x)-PI/2.0f;
|
||||
return m_localup.z < 0.0f ? a-PI : a;
|
||||
}
|
||||
|
||||
void
|
||||
Camera::turn(float yaw, float pitch)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
Quat r = Quat::rotation(yaw, rw::makeV3d(0.0f, 0.0f, 1.0f));
|
||||
dir = rotate(dir, r);
|
||||
m_localup = rotate(m_localup, r);
|
||||
|
||||
V3d right = normalize(cross(dir, m_localup));
|
||||
r = Quat::rotation(pitch, right);
|
||||
dir = rotate(dir, r);
|
||||
m_localup = normalize(cross(right, dir));
|
||||
if(m_localup.z >= 0.0) m_up.z = 1.0;
|
||||
else m_up.z = -1.0f;
|
||||
|
||||
m_target = add(m_position, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::orbit(float yaw, float pitch)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
Quat r = Quat::rotation(yaw, rw::makeV3d(0.0f, 0.0f, 1.0f));
|
||||
dir = rotate(dir, r);
|
||||
m_localup = rotate(m_localup, r);
|
||||
|
||||
V3d right = normalize(cross(dir, m_localup));
|
||||
r = Quat::rotation(-pitch, right);
|
||||
dir = rotate(dir, r);
|
||||
m_localup = normalize(cross(right, dir));
|
||||
if(m_localup.z >= 0.0) m_up.z = 1.0;
|
||||
else m_up.z = -1.0f;
|
||||
|
||||
m_position = sub(m_target, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::dolly(float dist)
|
||||
{
|
||||
V3d dir = setlength(sub(m_target, m_position), dist);
|
||||
m_position = add(m_position, dir);
|
||||
m_target = add(m_target, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::zoom(float dist)
|
||||
{
|
||||
V3d dir = sub(m_target, m_position);
|
||||
float curdist = length(dir);
|
||||
if(dist >= curdist)
|
||||
dist = curdist-0.01f;
|
||||
dir = setlength(dir, dist);
|
||||
m_position = add(m_position, dir);
|
||||
}
|
||||
|
||||
void
|
||||
Camera::pan(float x, float y)
|
||||
{
|
||||
V3d dir = normalize(sub(m_target, m_position));
|
||||
V3d right = normalize(cross(dir, m_up));
|
||||
V3d localup = normalize(cross(right, dir));
|
||||
dir = add(scale(right, x), scale(localup, y));
|
||||
m_position = add(m_position, dir);
|
||||
m_target = add(m_target, dir);
|
||||
}
|
||||
|
||||
float
|
||||
Camera::distanceTo(V3d v)
|
||||
{
|
||||
return length(sub(m_position, v));
|
||||
}
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
m_position.set(0.0f, 6.0f, 0.0f);
|
||||
m_target.set(0.0f, 0.0f, 0.0f);
|
||||
m_up.set(0.0f, 0.0f, 1.0f);
|
||||
m_localup = m_up;
|
||||
m_fov = 70.0f;
|
||||
m_aspectRatio = 1.0f;
|
||||
m_near = 0.1f;
|
||||
m_far = 100.0f;
|
||||
m_rwcam = NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
class Camera
|
||||
{
|
||||
public:
|
||||
rw::Camera *m_rwcam;
|
||||
rw::V3d m_position;
|
||||
rw::V3d m_target;
|
||||
rw::V3d m_up;
|
||||
rw::V3d m_localup;
|
||||
|
||||
float m_fov, m_aspectRatio;
|
||||
float m_near, m_far;
|
||||
|
||||
|
||||
void setTarget(rw::V3d target);
|
||||
float getHeading(void);
|
||||
|
||||
void turn(float yaw, float pitch);
|
||||
void orbit(float yaw, float pitch);
|
||||
void dolly(float dist);
|
||||
void zoom(float dist);
|
||||
void pan(float x, float y);
|
||||
|
||||
void update(void);
|
||||
float distanceTo(rw::V3d v);
|
||||
Camera(void);
|
||||
};
|
|
@ -0,0 +1,181 @@
|
|||
#include <rw.h>
|
||||
#include <skeleton.h>
|
||||
#include "camera.h"
|
||||
#include <assert.h>
|
||||
|
||||
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
||||
Camera *camera;
|
||||
rw::Clump *clump;
|
||||
rw::World *world;
|
||||
rw::EngineStartParams engineStartParams;
|
||||
|
||||
void
|
||||
Init(void)
|
||||
{
|
||||
sk::globals.windowtitle = "Clump viewer";
|
||||
sk::globals.width = 640;
|
||||
sk::globals.height = 480;
|
||||
sk::globals.quit = 0;
|
||||
}
|
||||
|
||||
bool
|
||||
attachPlugins(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
InitRW(void)
|
||||
{
|
||||
// rw::platform = rw::PLATFORM_D3D8;
|
||||
if(!sk::InitRW())
|
||||
return false;
|
||||
|
||||
char *filename = "teapot.dff";
|
||||
rw::StreamFile in;
|
||||
if(in.open(filename, "rb") == NULL){
|
||||
printf("couldn't open file\n");
|
||||
return false;
|
||||
}
|
||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||
clump = rw::Clump::streamRead(&in);
|
||||
assert(clump);
|
||||
in.close();
|
||||
|
||||
clump->getFrame()->translate(&zero, rw::COMBINEREPLACE);
|
||||
|
||||
FORLIST(lnk, clump->atomics){
|
||||
rw::Atomic *a = rw::Atomic::fromClump(lnk);
|
||||
if(a->pipeline && a->pipeline->platform != rw::platform)
|
||||
a->pipeline = NULL;
|
||||
}
|
||||
|
||||
|
||||
world = rw::World::create();
|
||||
|
||||
rw::Light *ambient = rw::Light::create(rw::Light::AMBIENT);
|
||||
ambient->setColor(0.2f, 0.2f, 0.2f);
|
||||
world->addLight(ambient);
|
||||
|
||||
rw::V3d xaxis = { 1.0f, 0.0f, 0.0f };
|
||||
rw::Light *direct = rw::Light::create(rw::Light::DIRECTIONAL);
|
||||
direct->setColor(0.8f, 0.8f, 0.8f);
|
||||
direct->setFrame(rw::Frame::create());
|
||||
direct->getFrame()->rotate(&xaxis, 180.0f, rw::COMBINEREPLACE);
|
||||
world->addLight(direct);
|
||||
|
||||
camera = new Camera;
|
||||
camera->m_rwcam = rw::Camera::create();
|
||||
camera->m_rwcam->setFrame(rw::Frame::create());
|
||||
camera->m_aspectRatio = 640.0f/480.0f;
|
||||
camera->m_near = 0.1f;
|
||||
camera->m_far = 450.0f;
|
||||
camera->m_target.set(0.0f, 0.0f, 0.0f);
|
||||
camera->m_position.set(0.0f, -10.0f, 0.0f);
|
||||
// camera->setPosition(Vec3(0.0f, 5.0f, 0.0f));
|
||||
// camera->setPosition(Vec3(0.0f, -70.0f, 0.0f));
|
||||
// camera->setPosition(Vec3(0.0f, -1.0f, 3.0f));
|
||||
camera->update();
|
||||
|
||||
world->addCamera(camera->m_rwcam);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Draw(float timeDelta)
|
||||
{
|
||||
static rw::RGBA clearcol = { 0x80, 0x80, 0x80, 0xFF };
|
||||
camera->m_rwcam->clear(&clearcol, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||
camera->update();
|
||||
camera->m_rwcam->beginUpdate();
|
||||
|
||||
clump->render();
|
||||
|
||||
camera->m_rwcam->endUpdate();
|
||||
camera->m_rwcam->showRaster();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KeyUp(int key)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
KeyDown(int key)
|
||||
{
|
||||
switch(key){
|
||||
case 'W':
|
||||
camera->orbit(0.0f, 0.1f);
|
||||
break;
|
||||
case 'S':
|
||||
camera->orbit(0.0f, -0.1f);
|
||||
break;
|
||||
case 'A':
|
||||
camera->orbit(-0.1f, 0.0f);
|
||||
break;
|
||||
case 'D':
|
||||
camera->orbit(0.1f, 0.0f);
|
||||
break;
|
||||
case sk::KEY_UP:
|
||||
camera->turn(0.0f, 0.1f);
|
||||
break;
|
||||
case sk::KEY_DOWN:
|
||||
camera->turn(0.0f, -0.1f);
|
||||
break;
|
||||
case sk::KEY_LEFT:
|
||||
camera->turn(0.1f, 0.0f);
|
||||
break;
|
||||
case sk::KEY_RIGHT:
|
||||
camera->turn(-0.1f, 0.0f);
|
||||
break;
|
||||
case 'R':
|
||||
camera->zoom(0.1f);
|
||||
break;
|
||||
case 'F':
|
||||
camera->zoom(-0.1f);
|
||||
break;
|
||||
case sk::KEY_ESC:
|
||||
sk::globals.quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sk::EventStatus
|
||||
AppEventHandler(sk::Event e, void *param)
|
||||
{
|
||||
using namespace sk;
|
||||
switch(e){
|
||||
case INITIALIZE:
|
||||
Init();
|
||||
return EVENTPROCESSED;
|
||||
case RWINITIALIZE:
|
||||
return ::InitRW() ? EVENTPROCESSED : EVENTERROR;
|
||||
case PLUGINATTACH:
|
||||
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
||||
case KEYDOWN:
|
||||
KeyDown(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case KEYUP:
|
||||
KeyUp(*(int*)param);
|
||||
return EVENTPROCESSED;
|
||||
case IDLE:
|
||||
Draw(*(float*)param);
|
||||
return EVENTPROCESSED;
|
||||
}
|
||||
return sk::EVENTNOTPROCESSED;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,437 @@
|
|||
#define GS_NONINTERLACED 0
|
||||
#define GS_INTERLACED 1
|
||||
|
||||
#define GS_NTSC 2
|
||||
#define GS_PAL 3
|
||||
#define GS_VESA1A 0x1a
|
||||
#define GS_VESA1B 0x1b
|
||||
#define GS_VESA1C 0x1c
|
||||
#define GS_VESA1D 0x1d
|
||||
#define GS_VESA2A 0x2a
|
||||
#define GS_VESA2B 0x2b
|
||||
#define GS_VESA2C 0x2c
|
||||
#define GS_VESA2D 0x2d
|
||||
#define GS_VESA2E 0x2e
|
||||
#define GS_VESA3B 0x3b
|
||||
#define GS_VESA3C 0x3c
|
||||
#define GS_VESA3D 0x3d
|
||||
#define GS_VESA3E 0x3e
|
||||
#define GS_VESA4A 0x4a
|
||||
#define GS_VESA4B 0x4b
|
||||
#define GS_DTV480P 0x50
|
||||
|
||||
#define GS_FIELD 0
|
||||
#define GS_FRAME 1
|
||||
|
||||
#define GS_PSMCT32 0
|
||||
#define GS_PSMCT24 1
|
||||
#define GS_PSMCT16 2
|
||||
#define GS_PSMCT16S 10
|
||||
#define GS_PS_GPU24 18
|
||||
|
||||
#define GS_PSMZ32 0
|
||||
#define GS_PSMZ24 1
|
||||
#define GS_PSMZ16 2
|
||||
#define GS_PSMZ16S 10
|
||||
|
||||
#define GS_ZTST_NEVER 0
|
||||
#define GS_ZTST_ALWAYS 1
|
||||
#define GS_ZTST_GREATER 2
|
||||
#define GS_ZTST_GEQUAL 3
|
||||
|
||||
#define GS_PRIM_POINT 0
|
||||
#define GS_PRIM_LINE 1
|
||||
#define GS_PRIM_LINE_STRIP 2
|
||||
#define GS_PRIM_TRI 3
|
||||
#define GS_PRIM_TRI_STRIP 4
|
||||
#define GS_PRIM_TRI_FAN 5
|
||||
#define GS_PRIM_SPRITE 6
|
||||
#define GS_PRIM_NO_SPEC 7
|
||||
#define GS_IIP_FLAT 0
|
||||
#define GS_IIP_GOURAUD 1
|
||||
|
||||
/* GS general purpose registers */
|
||||
|
||||
#define GS_PRIM 0x00
|
||||
#define GS_RGBAQ 0x01
|
||||
#define GS_ST 0x02
|
||||
#define GS_UV 0x03
|
||||
#define GS_XYZF2 0x04
|
||||
#define GS_XYZ2 0x05
|
||||
#define GS_TEX0_1 0x06
|
||||
#define GS_TEX0_2 0x07
|
||||
#define GS_CLAMP_1 0x08
|
||||
#define GS_CLAMP_2 0x09
|
||||
#define GS_FOG 0x0a
|
||||
#define GS_XYZF3 0x0c
|
||||
#define GS_XYZ3 0x0d
|
||||
#define GS_TEX1_1 0x14
|
||||
#define GS_TEX1_2 0x15
|
||||
#define GS_TEX2_1 0x16
|
||||
#define GS_TEX2_2 0x17
|
||||
#define GS_XYOFFSET_1 0x18
|
||||
#define GS_XYOFFSET_2 0x19
|
||||
#define GS_PRMODECONT 0x1a
|
||||
#define GS_PRMODE 0x1b
|
||||
#define GS_TEXCLUT 0x1c
|
||||
#define GS_SCANMSK 0x22
|
||||
#define GS_MIPTBP1_1 0x34
|
||||
#define GS_MIPTBP1_2 0x35
|
||||
#define GS_MIPTBP2_1 0x36
|
||||
#define GS_MIPTBP2_2 0x37
|
||||
#define GS_TEXA 0x3b
|
||||
#define GS_FOGCOL 0x3d
|
||||
#define GS_TEXFLUSH 0x3f
|
||||
#define GS_SCISSOR_1 0x40
|
||||
#define GS_SCISSOR_2 0x41
|
||||
#define GS_ALPHA_1 0x42
|
||||
#define GS_ALPHA_2 0x43
|
||||
#define GS_DIMX 0x44
|
||||
#define GS_DTHE 0x45
|
||||
#define GS_COLCLAMP 0x46
|
||||
#define GS_TEST_1 0x47
|
||||
#define GS_TEST_2 0x48
|
||||
#define GS_PABE 0x49
|
||||
#define GS_FBA_1 0x4a
|
||||
#define GS_FBA_2 0x4b
|
||||
#define GS_FRAME_1 0x4c
|
||||
#define GS_FRAME_2 0x4d
|
||||
#define GS_ZBUF_1 0x4e
|
||||
#define GS_ZBUF_2 0x4f
|
||||
#define GS_BITBLTBUF 0x50
|
||||
#define GS_TRXPOS 0x51
|
||||
#define GS_TRXREG 0x52
|
||||
#define GS_TRXDIR 0x53
|
||||
#define GS_HWREG 0x54
|
||||
#define GS_SIGNAL 0x60
|
||||
#define GS_FINISH 0x61
|
||||
#define GS_LABEL 0x62
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 EN1 : 1;
|
||||
uint64 EN2 : 1;
|
||||
uint64 CRTMD : 3;
|
||||
uint64 MMOD : 1;
|
||||
uint64 AMOD : 1;
|
||||
uint64 SLBG : 1;
|
||||
uint64 ALP : 8;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsPmode;
|
||||
|
||||
#define GS_MAKE_PMODE(EN1,EN2,MMOD,AMOD,SLBG,ALP) \
|
||||
(BIT64(EN1,0) | BIT64(EN2,1) | BIT64(1,2) | \
|
||||
BIT64(MMOD,5) | BIT64(AMOD,6) | BIT64(SLBG,7) | BIT64(ALP,8))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 INT : 1;
|
||||
uint64 FFMD : 1;
|
||||
uint64 DPMS : 2;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsSmode2;
|
||||
|
||||
#define GS_MAKE_SMODE2(INT,FFMD,DPMS) \
|
||||
(BIT64(INT,0) | BIT64(FFMD,1) | BIT64(DPMS,2))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 FBP : 9;
|
||||
uint64 FBW : 6;
|
||||
uint64 PSM : 5;
|
||||
uint64 : 12;
|
||||
uint64 DBX : 11;
|
||||
uint64 DBY : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsDispfb;
|
||||
|
||||
#define GS_MAKE_DISPFB(FBP,FBW,PSM,DBX,DBY) \
|
||||
(BIT64(FBP,0) | BIT64(FBW,9) | BIT64(PSM,15) | \
|
||||
BIT64(DBX,32) | BIT64(DBY,43))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 DX : 12;
|
||||
uint64 DY : 11;
|
||||
uint64 MAGH : 4;
|
||||
uint64 MAGV : 2;
|
||||
uint64 : 3;
|
||||
uint64 DW : 12;
|
||||
uint64 DH : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsDisplay;
|
||||
|
||||
#define GS_MAKE_DISPLAY(DX,DY,MAGH,MAGV,DW,DH) \
|
||||
(BIT64(DX,0) | BIT64(DY,12) | BIT64(MAGH,23) | \
|
||||
BIT64(MAGV,27) | BIT64(DW,32) | BIT64(DH,44))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 EXBP : 14;
|
||||
uint64 EXBW : 6;
|
||||
uint64 FBIN : 2;
|
||||
uint64 WFFMD : 1;
|
||||
uint64 EMODA : 2;
|
||||
uint64 EMODC : 2;
|
||||
uint64 : 5;
|
||||
uint64 WDX : 11;
|
||||
uint64 WDY : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsExtbuf;
|
||||
|
||||
#define GS_MAKE_EXTBUF(EXBP,EXBW,FBIN,WFFMD,EMODA,EMODC,WDX,WDY) \
|
||||
(BIT64(EXBP,0) | BIT64(EXBW,14) | BIT64(FBIN,20) | \
|
||||
BIT64(WFFMD,22) | BIT64(EMODA,23) | BIT64(EMODC,25) | \
|
||||
BIT64(WDX,32) | BIT64(WDY,43))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 SX : 12;
|
||||
uint64 SY : 11;
|
||||
uint64 SMPH : 4;
|
||||
uint64 SMPV : 2;
|
||||
uint64 : 3;
|
||||
uint64 WW : 12;
|
||||
uint64 WH : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsExtdata;
|
||||
|
||||
#define GS_MAKE_EXTDATA(SX,SY,SMPH,SMPV,WW,WH) \
|
||||
(BIT64(SX,0) | BIT64(SY,12) | BIT64(SMPH,23) | \
|
||||
BIT64(SMPV,27) | BIT64(WW,32) | BIT64(WH,44))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 WRITE : 1;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsExtwrite;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 R : 8;
|
||||
uint64 G : 8;
|
||||
uint64 B : 8;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsBgcolor;
|
||||
|
||||
#define GS_MAKE_BGCOLOR(R,G,B) \
|
||||
(BIT64(R,0) | BIT64(G,8) | BIT64(B,16))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 SIGNAL : 1;
|
||||
uint64 FINISH : 1;
|
||||
uint64 HSINT : 1;
|
||||
uint64 VSINT : 1;
|
||||
uint64 EDWINT : 1;
|
||||
uint64 : 3;
|
||||
uint64 FLUSH : 1;
|
||||
uint64 RESET : 1;
|
||||
uint64 : 2;
|
||||
uint64 NFIELD : 1;
|
||||
uint64 FIELD : 1;
|
||||
uint64 FIFO : 2;
|
||||
uint64 REV : 8;
|
||||
uint64 ID : 8;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsCsr;
|
||||
|
||||
#define GS_CSR_SIGNAL_O 0
|
||||
#define GS_CSR_FINISH_O 1
|
||||
#define GS_CSR_HSINT_O 2
|
||||
#define GS_CSR_VSINT_O 3
|
||||
#define GS_CSR_EDWINT_O 4
|
||||
#define GS_CSR_FLUSH_O 8
|
||||
#define GS_CSR_RESET_O 9
|
||||
#define GS_CSR_NFIELD_O 12
|
||||
#define GS_CSR_FIELD_O 13
|
||||
#define GS_CSR_FIFO_O 14
|
||||
#define GS_CSR_REV_O 16
|
||||
#define GS_CSR_ID_O 24
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 : 8;
|
||||
uint64 SIGMSK : 1;
|
||||
uint64 FINISHMSK : 1;
|
||||
uint64 HSMSKMSK : 1;
|
||||
uint64 VSMSKMSK : 1;
|
||||
uint64 EDWMSKMSK : 1;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsImr;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 DIR : 1;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsBusdir;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 SIGID : 32;
|
||||
uint64 LBLID : 32;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsSiglblid;
|
||||
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 FBP : 9;
|
||||
uint64 : 7;
|
||||
uint64 FBW : 6;
|
||||
uint64 : 2;
|
||||
uint64 PSM : 6;
|
||||
uint64 : 2;
|
||||
uint64 FBMSK : 32;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsFrame;
|
||||
|
||||
#define GS_MAKE_FRAME(FBP,FBW,PSM,FBMASK) \
|
||||
(BIT64(FBP,0) | BIT64(FBW,16) | BIT64(PSM,24) | BIT64(FBMASK,32))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 ZBP : 9;
|
||||
uint64 : 15;
|
||||
uint64 PSM : 4;
|
||||
uint64 : 4;
|
||||
uint64 ZMSDK : 1;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsZbuf;
|
||||
|
||||
#define GS_MAKE_ZBUF(ZBP,PSM,ZMSK) \
|
||||
(BIT64(ZBP,0) | BIT64(PSM,24) | BIT64(ZMSK,32))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 OFX : 16;
|
||||
uint64 : 16;
|
||||
uint64 OFY : 16;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsXyOffset;
|
||||
|
||||
#define GS_MAKE_XYOFFSET(OFX,OFY) \
|
||||
(BIT64(OFX,0) | BIT64(OFY,32))
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct {
|
||||
uint64 SCAX0 : 11;
|
||||
uint64 : 5;
|
||||
uint64 SCAX1 : 11;
|
||||
uint64 : 5;
|
||||
uint64 SCAY0 : 11;
|
||||
uint64 : 5;
|
||||
uint64 SCAY1 : 11;
|
||||
} f;
|
||||
uint64 d;
|
||||
} GsScissor;
|
||||
|
||||
#define GS_MAKE_SCISSOR(SCAX0,SCAX1,SCAY0,SCAY1) \
|
||||
(BIT64(SCAX0,0) | BIT64(SCAX1,16) | BIT64(SCAY0,32) | BIT64(SCAY1,48))
|
||||
|
||||
#define GS_MAKE_TEST(ATE,ATST,AREF,AFAIL,DATE,DATM,ZTE,ZTST) \
|
||||
(BIT64(ATE,0) | BIT64(ATST,1) | BIT64(AREF,4) | BIT64(AFAIL,12) | \
|
||||
BIT64(DATE,14) | BIT64(DATM,15) | BIT64(ZTE,16) | BIT64(ZTST,17))
|
||||
|
||||
#define GS_MAKE_PRIM(PRIM,IIP,TME,FGE,ABE,AA1,FST,CTXT,FIX) \
|
||||
(BIT64(PRIM,0) | BIT64(IIP,3) | BIT64(TME,4) | BIT64(FGE,5) | \
|
||||
BIT64(ABE,6) | BIT64(AA1,7) | BIT64(FST,8) | BIT64(CTXT,9) | BIT64(FIX,10))
|
||||
|
||||
#define GS_MAKE_RGBAQ(R,G,B,A,Q) \
|
||||
(BIT64(R,0) | BIT64(G,8) | BIT64(B,16) | BIT64(A,24) | BIT64(Q,32))
|
||||
|
||||
#define GS_MAKE_XYZ(X,Y,Z) \
|
||||
(BIT64(X,0) | BIT64(Y,16) | BIT64(Z,32))
|
||||
|
||||
#define GIF_PACKED 0
|
||||
#define GIF_REGLIST 1
|
||||
#define GIF_IMAGE 2
|
||||
|
||||
#define GIF_MAKE_TAG(NLOOP,EOP,PRE,PRIM,FLG,NREG) \
|
||||
(BIT64(NLOOP,0) | BIT64(EOP,15) | BIT64(PRE,46) | \
|
||||
BIT64(PRIM,47) | BIT64(FLG,58) | BIT64(NREG,60))
|
||||
|
||||
/* This is global and not tied to a user context because
|
||||
* it is set up by kernel functions and not really changed
|
||||
* afterwards. */
|
||||
typedef struct GsCrtState GsCrtState;
|
||||
struct GsCrtState
|
||||
{
|
||||
short inter, mode, ff;
|
||||
};
|
||||
extern GsCrtState gsCrtState;
|
||||
|
||||
typedef struct GsDispCtx GsDispCtx;
|
||||
struct GsDispCtx
|
||||
{
|
||||
// two circuits
|
||||
GsPmode pmode;
|
||||
GsDispfb dispfb1;
|
||||
GsDispfb dispfb2;
|
||||
GsDisplay display1;
|
||||
GsDisplay display2;
|
||||
GsBgcolor bgcolor;
|
||||
};
|
||||
|
||||
typedef struct GsDrawCtx GsDrawCtx;
|
||||
struct GsDrawCtx
|
||||
{
|
||||
//two contexts
|
||||
uint128 gifTag;
|
||||
GsFrame frame1;
|
||||
uint64 ad_frame1;
|
||||
GsFrame frame2;
|
||||
uint64 ad_frame2;
|
||||
GsZbuf zbuf1;
|
||||
uint64 ad_zbuf1;
|
||||
GsZbuf zbuf2;
|
||||
uint64 ad_zbuf2;
|
||||
GsXyOffset xyoffset1;
|
||||
uint64 ad_xyoffset1;
|
||||
GsXyOffset xyoffset2;
|
||||
uint64 ad_xyoffset2;
|
||||
GsScissor scissor1;
|
||||
uint64 ad_scissor1;
|
||||
GsScissor scissor2;
|
||||
uint64 ad_scissor2;
|
||||
};
|
||||
|
||||
typedef struct GsCtx GsCtx;
|
||||
struct GsCtx
|
||||
{
|
||||
// display context; two buffers
|
||||
GsDispCtx disp[2];
|
||||
// draw context; two buffers
|
||||
GsDrawCtx draw[2];
|
||||
};
|
|
@ -0,0 +1,744 @@
|
|||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
#include <rw.h>
|
||||
using rw::uint8;
|
||||
using rw::uint16;
|
||||
using rw::uint32;
|
||||
using rw::uint64;
|
||||
using rw::int8;
|
||||
using rw::int16;
|
||||
using rw::int32;
|
||||
using rw::int64;
|
||||
using rw::bool32;
|
||||
using rw::float32;
|
||||
typedef uint8 uchar;
|
||||
typedef uint16 ushort;
|
||||
typedef uint32 uint;
|
||||
|
||||
#define WIDTH 640
|
||||
#define HEIGHT 448
|
||||
|
||||
#include "ps2.h"
|
||||
|
||||
// getting undefined references otherwise :/
|
||||
int *__errno() { return &errno; }
|
||||
|
||||
// NONINTERLACED and FRAME have half of the FIELD vertical resolution!
|
||||
// NONINTERLACED has half the vertical units
|
||||
|
||||
uint128 packetbuf[128];
|
||||
uint128 vuXYZScale;
|
||||
uint128 vuXYZOffset;
|
||||
extern uint32 geometryCall[];
|
||||
extern uint32 skinPipe[];
|
||||
|
||||
uint128 *curVifPtr;
|
||||
uint128 lightpacket[128];
|
||||
int32 numLightQ;
|
||||
|
||||
|
||||
|
||||
rw::World *world;
|
||||
rw::Camera *camera;
|
||||
|
||||
|
||||
int frames;
|
||||
|
||||
void
|
||||
printquad(uint128 p)
|
||||
{
|
||||
uint64 *lp;
|
||||
lp = (uint64*)&p;
|
||||
printf("%016lx %016lx\n", lp[1], lp[0]);
|
||||
}
|
||||
|
||||
void
|
||||
printquad4(uint128 p)
|
||||
{
|
||||
uint32 *lp;
|
||||
lp = (uint32*)&p;
|
||||
printf("%08x %08x %08x %08x\n", lp[0], lp[1], lp[2], lp[3]);
|
||||
}
|
||||
|
||||
void
|
||||
dump4(uint128 *p, int n)
|
||||
{
|
||||
printf("data at %p\n", p);
|
||||
while(n--)
|
||||
printquad4(*p++);
|
||||
}
|
||||
|
||||
struct DmaChannel {
|
||||
uint32 chcr; uint32 pad0[3];
|
||||
uint32 madr; uint32 pad1[3];
|
||||
uint32 qwc; uint32 pad2[3];
|
||||
uint32 tadr; uint32 pad3[3];
|
||||
uint32 asr0; uint32 pad4[3];
|
||||
uint32 asr1; uint32 pad5[3];
|
||||
uint32 pad6[8];
|
||||
uint32 sadr;
|
||||
};
|
||||
|
||||
static struct DmaChannel *dmaChannels[] = {
|
||||
(struct DmaChannel *) &D0_CHCR,
|
||||
(struct DmaChannel *) &D1_CHCR,
|
||||
(struct DmaChannel *) &D2_CHCR,
|
||||
(struct DmaChannel *) &D3_CHCR,
|
||||
(struct DmaChannel *) &D4_CHCR,
|
||||
(struct DmaChannel *) &D5_CHCR,
|
||||
(struct DmaChannel *) &D6_CHCR,
|
||||
(struct DmaChannel *) &D7_CHCR,
|
||||
(struct DmaChannel *) &D8_CHCR,
|
||||
(struct DmaChannel *) &D9_CHCR
|
||||
};
|
||||
|
||||
void
|
||||
dmaReset(void)
|
||||
{
|
||||
/* don't clear the SIF channels */
|
||||
int doclear[] = { 1, 1, 1, 1, 1, 0, 0, 0, 1, 1 };
|
||||
int i;
|
||||
|
||||
D_CTRL = 0;
|
||||
for(i = 0; i < 10; i++)
|
||||
if(doclear[i]){
|
||||
dmaChannels[i]->chcr = 0;
|
||||
dmaChannels[i]->madr = 0;
|
||||
dmaChannels[i]->qwc = 0;
|
||||
dmaChannels[i]->tadr = 0;
|
||||
dmaChannels[i]->asr0 = 0;
|
||||
dmaChannels[i]->asr1 = 0;
|
||||
dmaChannels[i]->sadr = 0;
|
||||
}
|
||||
D_CTRL = 1;
|
||||
}
|
||||
|
||||
void
|
||||
waitDMA(volatile uint32 *chcr)
|
||||
{
|
||||
while(*chcr & (1<<8));
|
||||
}
|
||||
|
||||
void
|
||||
qwcpy(uint128 *dst, uint128 *src, int n)
|
||||
{
|
||||
while(n--) *dst++ = *src++;
|
||||
}
|
||||
|
||||
void
|
||||
toGIF(void *src, int n)
|
||||
{
|
||||
FlushCache(0);
|
||||
D2_QWC = n;
|
||||
D2_MADR = (uint32)src;
|
||||
D2_CHCR = 1<<8;
|
||||
waitDMA(&D2_CHCR);
|
||||
}
|
||||
|
||||
void
|
||||
toGIFchain(void *src)
|
||||
{
|
||||
FlushCache(0);
|
||||
D2_QWC = 0;
|
||||
D2_TADR = (uint32)src & 0x0FFFFFFF;
|
||||
D2_CHCR = 1<<0 | 1<<2 | 1<<6 | 1<<8;
|
||||
waitDMA(&D2_CHCR);
|
||||
}
|
||||
|
||||
void
|
||||
toVIF1chain(void *src)
|
||||
{
|
||||
FlushCache(0);
|
||||
D1_QWC = 0;
|
||||
D1_TADR = (uint32)src & 0x0FFFFFFF;
|
||||
D1_CHCR = 1<<0 | 1<<2 | 1<<6 | 1<<8;
|
||||
waitDMA(&D1_CHCR);
|
||||
}
|
||||
|
||||
|
||||
GsCrtState gsCrtState;
|
||||
|
||||
int psmsizemap[64] = {
|
||||
4, // GS_PSMCT32
|
||||
4, // GS_PSMCT24
|
||||
2, // GS_PSMCT16
|
||||
0, 0, 0, 0, 0, 0, 0,
|
||||
2, // GS_PSMCT16S
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, // GS_PSMZ32
|
||||
4, // GS_PSMZ24
|
||||
2, // GS_PSMZ16
|
||||
2, // GS_PSMZ16S
|
||||
0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
void
|
||||
GsResetCrt(uchar inter, uchar mode, uchar ff)
|
||||
{
|
||||
gsCrtState.inter = inter;
|
||||
gsCrtState.mode = mode;
|
||||
gsCrtState.ff = ff;
|
||||
GS_CSR = 1 << GS_CSR_RESET_O;
|
||||
__asm__("sync.p; nop");
|
||||
GsPutIMR(0xff00);
|
||||
SetGsCrt(gsCrtState.inter, gsCrtState.mode, gsCrtState.ff);
|
||||
}
|
||||
|
||||
uint gsAllocPtr = 0;
|
||||
|
||||
void
|
||||
GsInitDispCtx(GsDispCtx *disp, int width, int height, int psm)
|
||||
{
|
||||
int magh, magv;
|
||||
int dx, dy;
|
||||
int dw, dh;
|
||||
|
||||
dx = gsCrtState.mode == GS_NTSC ? 636 : 656;
|
||||
dy = gsCrtState.mode == GS_NTSC ? 25 : 36;
|
||||
magh = 2560/width - 1;
|
||||
magv = 0;
|
||||
dw = 2560-1;
|
||||
dh = height-1;
|
||||
|
||||
if(gsCrtState.inter == GS_INTERLACED){
|
||||
dy *= 2;
|
||||
if(gsCrtState.ff == GS_FRAME)
|
||||
dh = (dh+1)*2-1;
|
||||
}
|
||||
|
||||
disp->pmode.d = GS_MAKE_PMODE(0, 1, 1, 1, 0, 0x00);
|
||||
disp->bgcolor.d = 0x404040;
|
||||
disp->dispfb1.d = 0;
|
||||
disp->dispfb2.d = GS_MAKE_DISPFB(0, width/64, psm, 0, 0);
|
||||
disp->display1.d = 0;
|
||||
disp->display2.d = GS_MAKE_DISPLAY(dx, dy, magh, magv, dw, dh);
|
||||
}
|
||||
|
||||
void
|
||||
GsPutDispCtx(GsDispCtx *disp)
|
||||
{
|
||||
GS_PMODE = disp->pmode.d;
|
||||
GS_DISPFB1 = disp->dispfb1.d;
|
||||
GS_DISPLAY1 = disp->display1.d;
|
||||
GS_DISPFB2 = disp->dispfb2.d;
|
||||
GS_DISPLAY2 = disp->display2.d;
|
||||
GS_BGCOLOR = disp->bgcolor.d;
|
||||
}
|
||||
|
||||
void
|
||||
GsInitDrawCtx(GsDrawCtx *draw, int width, int height, int psm, int zpsm)
|
||||
{
|
||||
MAKE128(draw->gifTag, 0xe,
|
||||
GIF_MAKE_TAG(8, 1, 0, 0, GIF_PACKED, 1));
|
||||
draw->frame1.d = GS_MAKE_FRAME(0, width/64, psm, 0);
|
||||
draw->ad_frame1 = GS_FRAME_1;
|
||||
draw->frame2.d = draw->frame1.d;
|
||||
draw->ad_frame2 = GS_FRAME_2;
|
||||
draw->zbuf1.d = GS_MAKE_ZBUF(0, zpsm, 0);
|
||||
draw->ad_zbuf1 = GS_ZBUF_1;
|
||||
draw->zbuf2.d = draw->zbuf1.d;
|
||||
draw->ad_zbuf2 = GS_ZBUF_2;
|
||||
draw->xyoffset1.d = GS_MAKE_XYOFFSET(2048<<4, 2048<<4);
|
||||
draw->ad_xyoffset1 = GS_XYOFFSET_1;
|
||||
draw->xyoffset2.d = draw->xyoffset1.d;
|
||||
draw->ad_xyoffset2 = GS_XYOFFSET_2;
|
||||
draw->scissor1.d = GS_MAKE_SCISSOR(0, width-1, 0, height-1);
|
||||
draw->ad_scissor1 = GS_SCISSOR_1;
|
||||
draw->scissor2.d = draw->scissor1.d;
|
||||
draw->ad_scissor2 = GS_SCISSOR_2;
|
||||
}
|
||||
|
||||
void
|
||||
GsPutDrawCtx(GsDrawCtx *draw)
|
||||
{
|
||||
printquad(*(uint128*)&draw->frame1);
|
||||
toGIF(draw, 9);
|
||||
}
|
||||
|
||||
void
|
||||
GsInitCtx(GsCtx *ctx, int width, int height, int psm, int zpsm)
|
||||
{
|
||||
uint fbsz, zbsz;
|
||||
uint fbp, zbp;
|
||||
fbsz = (width*height*psmsizemap[psm] + 2047)/2048;
|
||||
zbsz = (width*height*psmsizemap[0x30|zpsm] + 2047)/2048;
|
||||
gsAllocPtr = 2*fbsz + zbsz;
|
||||
fbp = fbsz;
|
||||
zbp = fbsz*2;
|
||||
|
||||
GsInitDispCtx(&ctx->disp[0], width, height, psm);
|
||||
GsInitDispCtx(&ctx->disp[1], width, height, psm);
|
||||
GsInitDrawCtx(&ctx->draw[0], width, height, psm, zpsm);
|
||||
GsInitDrawCtx(&ctx->draw[1], width, height, psm, zpsm);
|
||||
ctx->disp[1].dispfb2.f.FBP = fbp/4;
|
||||
ctx->draw[0].frame1.f.FBP = fbp/4;
|
||||
ctx->draw[0].frame2.f.FBP = fbp/4;
|
||||
ctx->draw[0].zbuf1.f.ZBP = zbp/4;
|
||||
ctx->draw[0].zbuf2.f.ZBP = zbp/4;
|
||||
ctx->draw[1].zbuf1.f.ZBP = zbp/4;
|
||||
ctx->draw[1].zbuf2.f.ZBP = zbp/4;
|
||||
}
|
||||
|
||||
void
|
||||
initrender(void)
|
||||
{
|
||||
uint128 *p, tmp;
|
||||
p = packetbuf;
|
||||
MAKE128(tmp, 0xe, GIF_MAKE_TAG(2, 1, 0, 0, GIF_PACKED, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_PRMODECONT, 1);
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_COLCLAMP, 1);
|
||||
*p++ = tmp;
|
||||
toGIF(packetbuf, 3);
|
||||
}
|
||||
|
||||
void
|
||||
clearscreen(int r, int g, int b)
|
||||
{
|
||||
int x, y;
|
||||
uint128 *p, tmp;
|
||||
p = packetbuf;
|
||||
|
||||
x = (2048 + 640)<<4;
|
||||
y = (2048 + 448)<<4;
|
||||
|
||||
MAKE128(tmp, 0xe, GIF_MAKE_TAG(5, 1, 0, 0, GIF_PACKED, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_TEST_1, GS_MAKE_TEST(0, 0, 0, 0, 0, 0, 1, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_PRIM, GS_MAKE_PRIM(GS_PRIM_SPRITE,0,0,0,0,0,0,0,0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(r, g, b, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(2048<<4, 2048<<4, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x, y, 0));
|
||||
*p++ = tmp;
|
||||
toGIF(packetbuf, 6);
|
||||
}
|
||||
|
||||
void
|
||||
drawtest(void)
|
||||
{
|
||||
int x0, x1, x2, x3;
|
||||
int y0, y1, y2;
|
||||
uint128 *p, tmp;
|
||||
int n;
|
||||
|
||||
x0 = 2048<<4;
|
||||
x1 = (2048 + 210)<<4;
|
||||
x2 = (2048 + 430)<<4;
|
||||
x3 = (2048 + 640)<<4;
|
||||
y0 = 2048<<4;
|
||||
y1 = (2048 + 224)<<4;
|
||||
y2 = (2048 + 448)<<4;
|
||||
|
||||
n = 2 + 3*7;
|
||||
p = packetbuf;
|
||||
MAKEQ(tmp, 0x70000000 | n+1, 0, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, 0xe, GIF_MAKE_TAG(n, 1, 0, 0, GIF_PACKED, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_TEST_1, GS_MAKE_TEST(0, 0, 0, 0, 0, 0, 1, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_PRIM, GS_MAKE_PRIM(GS_PRIM_SPRITE,0,0,0,0,0,0,0,0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 0, 0, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x0, y0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(0, 255, 0, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(0, 0, 255, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x3, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(0, 255, 255, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x0, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y2, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 0, 255, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x1, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y2, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 255, 0, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x2, y1, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x3, y2, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_RGBAQ, GS_MAKE_RGBAQ(255, 255, 255, 0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ((2048+20)<<4, y0, 0));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYZ2, GS_MAKE_XYZ(x3, (2048+20)<<4, 0));
|
||||
*p++ = tmp;
|
||||
toGIFchain(packetbuf);
|
||||
}
|
||||
|
||||
void
|
||||
drawtri(void)
|
||||
{
|
||||
uint128 *p, tmp;
|
||||
uint32 *ip;
|
||||
int nverts, n;
|
||||
|
||||
nverts = 3;
|
||||
n = 2*nverts;
|
||||
p = packetbuf;
|
||||
MAKEQ(tmp, 0x70000000 | n+1, 0, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, (0x5<<4) | 0x1,
|
||||
GIF_MAKE_TAG(nverts, 1, 1, GS_MAKE_PRIM(GS_PRIM_TRI, 1, 0, 0, 0, 0, 0, 0, 0), GIF_PACKED, 2));
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, 255, 0, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, (2048+85)<<4, (2048+70)<<4, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, 0, 255, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, (2048+260)<<4, (2048+200)<<4, 0, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, 0, 0, 255, 0);
|
||||
*p++ = tmp;
|
||||
MAKEQ(tmp, (2048+180)<<4, (2048+350)<<4, 0, 0);
|
||||
*p++ = tmp;
|
||||
toGIFchain(packetbuf);
|
||||
}
|
||||
|
||||
void
|
||||
printMatrix(rw::Matrix *m)
|
||||
{
|
||||
rw::V3d *x = &m->right;
|
||||
rw::V3d *y = &m->up;
|
||||
rw::V3d *z = &m->at;
|
||||
rw::V3d *w = &m->pos;
|
||||
printf(
|
||||
"[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
|
||||
" [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
|
||||
" [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
|
||||
" [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n"
|
||||
" %08x == flags\n",
|
||||
x->x, y->x, z->x, w->x,
|
||||
x->y, y->y, z->y, w->y,
|
||||
x->z, y->z, z->z, w->z,
|
||||
0.0f, 0.0f, 0.0f, 1.0f,
|
||||
m->flags);
|
||||
}
|
||||
|
||||
// This is not proper data, just for testing
|
||||
void
|
||||
setupLight(rw::Atomic *atomic)
|
||||
{
|
||||
using namespace rw;
|
||||
Matrix *lightmat;
|
||||
float32 *lp;
|
||||
|
||||
numLightQ = 0;
|
||||
lp = (float32*)lightpacket;
|
||||
|
||||
// TODO: this is the wrong matrix. we actually want to
|
||||
// transform the light, not all normals.
|
||||
lightmat = atomic->getFrame()->getLTM();
|
||||
*lp++ = lightmat->right.x;
|
||||
*lp++ = lightmat->right.y;
|
||||
*lp++ = lightmat->right.z;
|
||||
*lp++ = 0.0f;
|
||||
*lp++ = lightmat->up.x;
|
||||
*lp++ = lightmat->up.y;
|
||||
*lp++ = lightmat->up.z;
|
||||
*lp++ = 0.0f;
|
||||
*lp++ = lightmat->at.x;
|
||||
*lp++ = lightmat->at.y;
|
||||
*lp++ = lightmat->at.z;
|
||||
*lp++ = 0.0f;
|
||||
*lp++ = lightmat->pos.x;
|
||||
*lp++ = lightmat->pos.y;
|
||||
*lp++ = lightmat->pos.z;
|
||||
*lp++ = 1.0f;
|
||||
// TODO: make a proper light block
|
||||
// ambient
|
||||
*lp++ = 80.0f;
|
||||
*lp++ = 80.0f;
|
||||
*lp++ = 80.0f;
|
||||
*lp++ = 0.0f;
|
||||
// directional
|
||||
*lp++ = 0.5f;
|
||||
*lp++ = -0.5f;
|
||||
*lp++ = -0.7071f;
|
||||
*lp++ = 0.0f;
|
||||
numLightQ = 6;
|
||||
}
|
||||
|
||||
void
|
||||
setupTransform(rw::Atomic *atomic, rw::Matrix *trans)
|
||||
{
|
||||
rw::Matrix::mult(trans, atomic->getFrame()->getLTM(), &camera->viewMatrix);
|
||||
}
|
||||
|
||||
enum {
|
||||
DMAcnt = 0x10000000,
|
||||
DMAref = 0x30000000,
|
||||
DMAcall = 0x50000000,
|
||||
DMAret = 0x60000000,
|
||||
DMAend = 0x70000000,
|
||||
|
||||
V4_32 = 0x6C
|
||||
};
|
||||
|
||||
#define UNPACK(type, nq, offset) ((type)<<24 | (nq)<<16 | (offset))
|
||||
#define STCYCL(WL,CL) (0x01000000 | (WL)<<8 | (CL))
|
||||
|
||||
void
|
||||
drawAtomic(rw::Atomic *atomic)
|
||||
{
|
||||
using namespace rw;
|
||||
|
||||
Matrix trans;
|
||||
Geometry *geo;
|
||||
ps2::ObjPipeline *pipe;
|
||||
ps2::MatPipeline *matpipe;
|
||||
Material *material;
|
||||
uint128 tmp, *lp;
|
||||
uint32 *vec;
|
||||
RGBAf color;
|
||||
int i;
|
||||
|
||||
geo = atomic->geometry;
|
||||
pipe = (ps2::ObjPipeline*)atomic->getPipeline();
|
||||
if(pipe->platform != PLATFORM_PS2)
|
||||
return;
|
||||
|
||||
setupLight(atomic);
|
||||
setupTransform(atomic, &trans);
|
||||
|
||||
curVifPtr = packetbuf;
|
||||
// upload lights
|
||||
MAKEQ(tmp, DMAcnt | numLightQ+8, 0, STCYCL(4,4), UNPACK(V4_32, numLightQ, 0x3d0));
|
||||
*curVifPtr++ = tmp;
|
||||
for(lp = lightpacket; numLightQ--;)
|
||||
*curVifPtr++ = *lp++;
|
||||
|
||||
// upload transformation matrix
|
||||
MAKEQ(tmp, 0, 0, STCYCL(4,4), UNPACK(V4_32, 4, 0x3f0));
|
||||
*curVifPtr++ = tmp;
|
||||
vec = (uint32*)&trans.right;
|
||||
MAKEQ(tmp, vec[0], vec[1], vec[2], vec[2]);
|
||||
*curVifPtr++ = tmp;
|
||||
vec = (uint32*)&trans.up;
|
||||
MAKEQ(tmp, vec[0], vec[1], vec[2], vec[2]);
|
||||
*curVifPtr++ = tmp;
|
||||
vec = (uint32*)&trans.at;
|
||||
MAKEQ(tmp, vec[0], vec[1], vec[2], vec[2]);
|
||||
*curVifPtr++ = tmp;
|
||||
vec = (uint32*)&trans.pos;
|
||||
MAKEQ(tmp, vec[0], vec[1], vec[2], vec[2]);
|
||||
*curVifPtr++ = tmp;
|
||||
|
||||
// upload camera/screen info
|
||||
MAKEQ(tmp, 0, 0, STCYCL(4,4), UNPACK(V4_32, 2, 0x3f7));
|
||||
*curVifPtr++ = tmp;
|
||||
*curVifPtr++ = vuXYZScale;
|
||||
*curVifPtr++ = vuXYZOffset;
|
||||
|
||||
assert(geo->instData != NULL);
|
||||
rw::ps2::InstanceDataHeader *instData =
|
||||
(rw::ps2::InstanceDataHeader*)geo->instData;
|
||||
rw::MeshHeader *meshHeader = geo->meshHeader;
|
||||
rw::Mesh *mesh;
|
||||
for(i = 0; i < instData->numMeshes; i++){
|
||||
material = instData->instanceMeshes[i].material;
|
||||
matpipe = pipe->groupPipeline;
|
||||
if(matpipe == nil)
|
||||
matpipe = (ps2::MatPipeline*)material->pipeline;
|
||||
if(matpipe == nil)
|
||||
matpipe = ps2::defaultMatPipe;
|
||||
|
||||
// call vu code
|
||||
MAKEQ(tmp, DMAcall, (uint32)skinPipe, 0, 0);
|
||||
*curVifPtr++ = tmp;
|
||||
// unpack GIF tag, material color, surface properties
|
||||
MAKEQ(tmp, DMAcnt | 3, 0, STCYCL(4,4), UNPACK(V4_32, 3, 0x3fa));
|
||||
*curVifPtr++ = tmp;
|
||||
MAKE128(tmp, 0x412,
|
||||
GIF_MAKE_TAG(0, 1, 1, GS_MAKE_PRIM(GS_PRIM_TRI_STRIP,1,0,0,0,0,0,0,0), GIF_PACKED, 3));
|
||||
*curVifPtr++ = tmp;
|
||||
convColor(&color, &material->color);
|
||||
color.alpha *= 128.0f/255.0f;
|
||||
MAKEQ(tmp, *(uint32*)&color.red, *(uint32*)&color.green,
|
||||
*(uint32*)&color.blue, *(uint32*)&color.alpha);
|
||||
*curVifPtr++ = tmp;
|
||||
MAKEQ(tmp, *(uint32*)&material->surfaceProps.ambient,
|
||||
*(uint32*)&material->surfaceProps.specular,
|
||||
*(uint32*)&material->surfaceProps.diffuse,
|
||||
0.0f); // extra
|
||||
*curVifPtr++ = tmp;
|
||||
// call geometry
|
||||
MAKEQ(tmp, DMAcall, (uint32)instData->instanceMeshes[i].data, 0x03000000, 0x02000000 | matpipe->vifOffset);
|
||||
*curVifPtr++ = tmp;
|
||||
}
|
||||
MAKEQ(tmp, DMAend, 0, 0, 0);
|
||||
*curVifPtr++ = tmp;
|
||||
for(lp = packetbuf; lp < curVifPtr; lp++)
|
||||
printquad4(*lp);
|
||||
toVIF1chain(packetbuf);
|
||||
}
|
||||
|
||||
void
|
||||
beginCamera(void)
|
||||
{
|
||||
uint128 *p, tmp;
|
||||
float32 *f;
|
||||
|
||||
p = packetbuf;
|
||||
MAKE128(tmp, 0xe, GIF_MAKE_TAG(2, 1, 0, 0, GIF_PACKED, 1));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_XYOFFSET_1, GS_MAKE_XYOFFSET(2048-WIDTH/2 <<4, 2048-HEIGHT/2 <<4));
|
||||
*p++ = tmp;
|
||||
MAKE128(tmp, GS_TEST_1, GS_MAKE_TEST(0, 0, 0, 0, 0, 0, 1, 2));
|
||||
*p++ = tmp;
|
||||
toGIF(packetbuf, 3);
|
||||
f = (float32*)&vuXYZScale;
|
||||
f[0] = WIDTH;
|
||||
f[1] = HEIGHT;
|
||||
f[2] = camera->zScale;
|
||||
f[3] = 0.0f;
|
||||
f = (float32*)&vuXYZOffset;
|
||||
f[0] = 2048.0f;
|
||||
f[1] = 2048.0f;
|
||||
f[2] = camera->zShift;
|
||||
f[3] = 0.0f;
|
||||
}
|
||||
|
||||
rw::EngineStartParams engineStartParams;
|
||||
|
||||
void
|
||||
pluginattach(void)
|
||||
{
|
||||
rw::ps2::registerPDSPlugin(40);
|
||||
rw::ps2::registerPluginPDSPipes();
|
||||
|
||||
rw::registerMeshPlugin();
|
||||
rw::registerNativeDataPlugin();
|
||||
rw::registerAtomicRightsPlugin();
|
||||
rw::registerMaterialRightsPlugin();
|
||||
rw::xbox::registerVertexFormatPlugin();
|
||||
rw::registerSkinPlugin();
|
||||
rw::registerHAnimPlugin();
|
||||
rw::registerMatFXPlugin();
|
||||
rw::registerUVAnimPlugin();
|
||||
rw::ps2::registerADCPlugin();
|
||||
}
|
||||
|
||||
bool32
|
||||
initrw(void)
|
||||
{
|
||||
rw::version = 0x34000;
|
||||
rw::platform = rw::PLATFORM_PS2;
|
||||
if(!rw::Engine::init())
|
||||
return 0;
|
||||
pluginattach();
|
||||
if(!rw::Engine::open())
|
||||
return 0;
|
||||
if(!rw::Engine::start(&engineStartParams))
|
||||
return 0;
|
||||
rw::engine->loadTextures = 0;
|
||||
|
||||
rw::TexDictionary::setCurrent(rw::TexDictionary::create());
|
||||
rw::Image::setSearchPath(".");
|
||||
|
||||
world = rw::World::create();
|
||||
camera = rw::Camera::create();
|
||||
camera->setFrame(rw::Frame::create());
|
||||
rw::V3d t = { 0.0f, 0.0f, -4.0f };
|
||||
// rw::V3d t = { 0.0f, 0.0f, -40.0f };
|
||||
camera->getFrame()->translate(&t, rw::COMBINEPOSTCONCAT);
|
||||
rw::V3d axis = { 0.0f, 1.0f, 0.0f };
|
||||
camera->getFrame()->rotate(&axis, 40.0f, rw::COMBINEPOSTCONCAT);
|
||||
camera->setNearPlane(0.1f);
|
||||
camera->setFarPlane(450.0f);
|
||||
camera->setFOV(60.0f, 4.0f/3.0f);
|
||||
world->addCamera(camera);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
vsynch(int id)
|
||||
{
|
||||
frames++;
|
||||
ExitHandler();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
FlushCache(0);
|
||||
if(!initrw()){
|
||||
printf("init failed!\n");
|
||||
for(;;);
|
||||
}
|
||||
|
||||
rw::uint32 len;
|
||||
rw::uint8 *data = rw::getFileContents("host:player.DFF", &len);
|
||||
// rw::uint8 *data = rw::getFileContents("host:od_newscafe_dy.dff", &len);
|
||||
rw::StreamMemory in;
|
||||
in.open(data, len);
|
||||
rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL);
|
||||
rw::Clump *clump = rw::Clump::streamRead(&in);
|
||||
in.close();
|
||||
delete[] data;
|
||||
|
||||
GsCtx gsCtx;
|
||||
|
||||
dmaReset();
|
||||
|
||||
// GsResetCrt(GS_NONINTERLACED, GS_NTSC, 0);
|
||||
// GsInitCtx(&gsCtx, 640, 224, GS_PSMCT32, GS_PSMZ32);
|
||||
|
||||
// GsResetCrt(GS_INTERLACED, GS_NTSC, GS_FRAME);
|
||||
// GsInitCtx(&gsCtx, 640, 224, GS_PSMCT32, GS_PSMZ32);
|
||||
|
||||
GsResetCrt(GS_INTERLACED, GS_NTSC, GS_FIELD);
|
||||
GsInitCtx(&gsCtx, WIDTH, HEIGHT, GS_PSMCT32, GS_PSMZ32);
|
||||
|
||||
initrender();
|
||||
|
||||
AddIntcHandler(2, vsynch, 0);
|
||||
EnableIntc(2);
|
||||
|
||||
GsPutDrawCtx(&gsCtx.draw[0]);
|
||||
GsPutDispCtx(&gsCtx.disp[1]);
|
||||
// PCSX2 needs a delay for some reason
|
||||
{ int i; for(i = 0; i < 1000000; i++); }
|
||||
clearscreen(0x80, 0x80, 0x80);
|
||||
// drawtest();
|
||||
// drawtri();
|
||||
|
||||
camera->beginUpdate();
|
||||
beginCamera();
|
||||
FORLIST(lnk, clump->atomics)
|
||||
drawAtomic(rw::Atomic::fromClump(lnk));
|
||||
camera->endUpdate();
|
||||
|
||||
printf("hello %p\n", clump);
|
||||
for(;;);
|
||||
// printf("");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/* FIFOs */
|
||||
#define VIF0_FIFO (*(volatile uint128*)0x10004000)
|
||||
#define VIF1_FIFO (*(volatile uint128*)0x10005000)
|
||||
#define GIF_FIFO (*(volatile uint128*)0x10006000)
|
||||
#define IPU_out_FIFO (*(volatile uint128*)0x10007000)
|
||||
#define IPU_in_FIFO (*(volatile uint128*)0x10007010)
|
||||
|
||||
/* DMA channels */
|
||||
// to VIF0
|
||||
#define D0_CHCR (*(volatile uint32*)0x10008000)
|
||||
#define D0_MADR (*(volatile uint32*)0x10008010)
|
||||
#define D0_QWC (*(volatile uint32*)0x10008020)
|
||||
#define D0_TADR (*(volatile uint32*)0x10008030)
|
||||
#define D0_ASR0 (*(volatile uint32*)0x10008040)
|
||||
#define D0_ASR1 (*(volatile uint32*)0x10008050)
|
||||
// VIF1
|
||||
#define D1_CHCR (*(volatile uint32*)0x10009000)
|
||||
#define D1_MADR (*(volatile uint32*)0x10009010)
|
||||
#define D1_QWC (*(volatile uint32*)0x10009020)
|
||||
#define D1_TADR (*(volatile uint32*)0x10009030)
|
||||
#define D1_ASR0 (*(volatile uint32*)0x10009040)
|
||||
#define D1_ASR1 (*(volatile uint32*)0x10009050)
|
||||
// to GIF
|
||||
#define D2_CHCR (*(volatile uint32*)0x1000a000)
|
||||
#define D2_MADR (*(volatile uint32*)0x1000a010)
|
||||
#define D2_QWC (*(volatile uint32*)0x1000a020)
|
||||
#define D2_TADR (*(volatile uint32*)0x1000a030)
|
||||
#define D2_ASR0 (*(volatile uint32*)0x1000a040)
|
||||
#define D2_ASR1 (*(volatile uint32*)0x1000a050)
|
||||
// fromIPU
|
||||
#define D3_CHCR (*(volatile uint32*)0x1000b000)
|
||||
#define D3_MADR (*(volatile uint32*)0x1000b010)
|
||||
#define D3_QWC (*(volatile uint32*)0x1000b020)
|
||||
// toIPU
|
||||
#define D4_CHCR (*(volatile uint32*)0x1000b400)
|
||||
#define D4_MADR (*(volatile uint32*)0x1000b410)
|
||||
#define D4_QWC (*(volatile uint32*)0x1000b420)
|
||||
#define D4_TADR (*(volatile uint32*)0x1000b430)
|
||||
// from SIF0
|
||||
#define D5_CHCR (*(volatile uint32*)0x1000c000)
|
||||
#define D5_MADR (*(volatile uint32*)0x1000c010)
|
||||
#define D5_QWC (*(volatile uint32*)0x1000c020)
|
||||
// to SIF1
|
||||
#define D6_CHCR (*(volatile uint32*)0x1000c400)
|
||||
#define D6_MADR (*(volatile uint32*)0x1000c410)
|
||||
#define D6_QWC (*(volatile uint32*)0x1000c420)
|
||||
#define D6_TADR (*(volatile uint32*)0x1000c430)
|
||||
// SIF2
|
||||
#define D7_CHCR (*(volatile uint32*)0x1000c800)
|
||||
#define D7_MADR (*(volatile uint32*)0x1000c810)
|
||||
#define D7_QWC (*(volatile uint32*)0x1000c820)
|
||||
// fromSPR
|
||||
#define D8_CHCR (*(volatile uint32*)0x1000d000)
|
||||
#define D8_MADR (*(volatile uint32*)0x1000d010)
|
||||
#define D8_QWC (*(volatile uint32*)0x1000d020)
|
||||
#define D8_SADR (*(volatile uint32*)0x1000d080)
|
||||
// toSPR
|
||||
#define D9_CHCR (*(volatile uint32*)0x1000d400)
|
||||
#define D9_MADR (*(volatile uint32*)0x1000d410)
|
||||
#define D9_QWC (*(volatile uint32*)0x1000d420)
|
||||
#define D9_TADR (*(volatile uint32*)0x1000d430)
|
||||
#define D9_SADR (*(volatile uint32*)0x1000d480)
|
||||
|
||||
/* DMA controller */
|
||||
#define D_CTRL (*(volatile uint32*)0x1000e000)
|
||||
#define D_STAT (*(volatile uint32*)0x1000e010)
|
||||
#define D_PCR (*(volatile uint32*)0x1000e020)
|
||||
#define D_SQWC (*(volatile uint32*)0x1000e030)
|
||||
#define D_RBSR (*(volatile uint32*)0x1000e040)
|
||||
#define D_RBOR (*(volatile uint32*)0x1000e050)
|
||||
#define D_STADR (*(volatile uint32*)0x1000e060)
|
||||
#define D_ENABLER (*(volatile uint32*)0x1000f520)
|
||||
#define D_ENABLEW (*(volatile uint32*)0x1000f590)
|
||||
|
||||
|
||||
/* GS privileged registers */
|
||||
#define GS_PMODE (*(volatile uint64*)0x12000000)
|
||||
#define GS_SMODE1 (*(volatile uint64*)0x12000010)
|
||||
#define GS_SMODE2 (*(volatile uint64*)0x12000020)
|
||||
#define GS_SRFSH (*(volatile uint64*)0x12000030)
|
||||
#define GS_SYNCH1 (*(volatile uint64*)0x12000040)
|
||||
#define GS_SYNCH2 (*(volatile uint64*)0x12000050)
|
||||
#define GS_SYNCV (*(volatile uint64*)0x12000060)
|
||||
#define GS_DISPFB1 (*(volatile uint64*)0x12000070)
|
||||
#define GS_DISPLAY1 (*(volatile uint64*)0x12000080)
|
||||
#define GS_DISPFB2 (*(volatile uint64*)0x12000090)
|
||||
#define GS_DISPLAY2 (*(volatile uint64*)0x120000a0)
|
||||
#define GS_EXTBUF (*(volatile uint64*)0x120000b0)
|
||||
#define GS_EXTDATA (*(volatile uint64*)0x120000c0)
|
||||
#define GS_EXTWRITE (*(volatile uint64*)0x120000d0)
|
||||
#define GS_BGCOLOR (*(volatile uint64*)0x120000e0)
|
||||
#define GS_CSR (*(volatile uint64*)0x12001000)
|
||||
#define GS_IMR (*(volatile uint64*)0x12001010)
|
||||
#define GS_BUSDIR (*(volatile uint64*)0x12001040)
|
||||
#define GS_SIGLBLID (*(volatile uint64*)0x12001080)
|
|
@ -0,0 +1,23 @@
|
|||
#include <kernel.h>
|
||||
|
||||
typedef int quad __attribute__((mode(TI)));
|
||||
typedef int int128 __attribute__((mode(TI)));
|
||||
typedef unsigned int uquad __attribute__((mode(TI)));
|
||||
typedef unsigned int uint128 __attribute__((mode(TI)));
|
||||
|
||||
#define MAKE128(RES,MSB,LSB) \
|
||||
__asm__ ( "pcpyld %0, %1, %2" : "=r" (RES) : "r" ((uint64)MSB), "r" ((uint64)LSB))
|
||||
#define UINT64(LOW,HIGH) (((uint64)HIGH)<<32 | ((uint64)LOW))
|
||||
#define MAKEQ(RES,W0,W1,W2,W3) MAKE128(RES,UINT64(W2,W3),UINT64(W0,W1))
|
||||
|
||||
#define BIT64(v,s) (((uint64)(v)) << (s))
|
||||
|
||||
#include "mem.h"
|
||||
#include "gs.h"
|
||||
|
||||
extern uint128 packetbuf[128];
|
||||
|
||||
void waitDMA(volatile uint32 *chcr);
|
||||
void toGIF(void *src, int n);
|
||||
|
||||
void drawcube(void);
|
|
@ -0,0 +1,93 @@
|
|||
.global defaultPipe
|
||||
|
||||
.equ vertexTop, 0x3d0
|
||||
.equ numInAttribs, 4
|
||||
.equ numOutAttribs, 3
|
||||
.equ numOutBuf, 2
|
||||
.equ vertCount, ((vertexTop-numOutBuf)/(numInAttribs*2+numOutAttribs*numOutBuf))
|
||||
.equ offset, (vertCount*numInAttribs)
|
||||
.equ outBuf1, (2*offset)
|
||||
.equ outSize, ((vertexTop-outBuf1-2)/2)
|
||||
.equ outBuf2, (outBuf1+outSize)
|
||||
|
||||
.equ lightMat, 0x3d0
|
||||
.equ ambientLight, 0x3d4
|
||||
.equ lightDir, 0x3d5
|
||||
|
||||
.equ matrix, 0x3f0
|
||||
.equ XYZScale, 0x3f7
|
||||
.equ XYZOffset, 0x3f8
|
||||
.equ gifTag, 0x3fa
|
||||
.equ matColor, 0x3fb
|
||||
.equ surfProps, 0x3fc
|
||||
|
||||
|
||||
.balign 16,0
|
||||
defaultPipe:
|
||||
DMAret *
|
||||
MPG 0, *
|
||||
.vu
|
||||
Start:
|
||||
#include "setup_persp.vu"
|
||||
Cnt:
|
||||
NOP XTOP VI02 ; input pointer
|
||||
NOP LQ VF01, gifTag(VI00)
|
||||
NOP XITOP VI01 ; vertex count
|
||||
NOP IADDIU VI05, VI00, 0x4000
|
||||
NOP IADD VI05, VI05, VI05
|
||||
NOP IOR VI05, VI05, VI01
|
||||
NOP SQ VF01, 0(VI12)
|
||||
NOP ISW.x VI05, 0(VI12)
|
||||
NOP IADDIU VI03, VI12, 1 ; output pointer
|
||||
NOP LQ VF18, lightMat(VI00)
|
||||
NOP LQ VF19, lightMat+1(VI00)
|
||||
NOP LQ VF20, lightMat+2(VI00)
|
||||
|
||||
Loop:
|
||||
NOP LQI VF01, (VI02++) ; vertex
|
||||
NOP LQI VF02, (VI02++) ; UV
|
||||
NOP LQI VF03, (VI02++) ; color
|
||||
NOP LQI VF04, (VI02++) ; normal
|
||||
|
||||
MULAw.xyzw ACC, VF31, VF00w NOP ; transform vertex
|
||||
MADDAx.xyw ACC, VF28, VF01x NOP
|
||||
MADDAy.xyw ACC, VF29, VF01y NOP
|
||||
MADDz.xyzw VF01, VF30, VF01z NOP
|
||||
ITOF0 VF03, VF03 NOP
|
||||
ITOF0[I] VF04, VF04 LOI 0.0078125 ; - normal scale
|
||||
NOP NOP
|
||||
NOP DIV Q, VF00w, VF01w
|
||||
NOP WAITQ
|
||||
MULq VF01, VF01, Q NOP ; perspective division
|
||||
MULi VF04, VF04, I NOP ; scale normal
|
||||
NOP MR32.z VF02, VF00
|
||||
NOP NOP
|
||||
SUB.w VF01, VF01, VF01 NOP
|
||||
MULAx.xyz ACC, VF18, VF04x NOP ; transform normal
|
||||
MADDAy.xyz ACC, VF19, VF04y NOP
|
||||
MADDz.xyz VF04, VF20, VF04z NOP
|
||||
ADD.xyz VF01, VF01, VF25 NOP
|
||||
MULq VF02, VF02, Q NOP
|
||||
NOP NOP
|
||||
FTOI0 VF03, VF03 NOP
|
||||
FTOI4 VF01, VF01 NOP
|
||||
NOP SQ VF04, -2(VI02) ; store normal
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP SQI VF02, (VI03++) ; STQ
|
||||
NOP SQI VF03, (VI03++) ; color
|
||||
NOP SQI VF01, (VI03++) ; vertex
|
||||
NOP IBNE VI01, VI00, Loop
|
||||
NOP NOP
|
||||
|
||||
#include "light.vu"
|
||||
|
||||
NOP XGKICK VI12
|
||||
NOP IADD VI15,VI00,VI12
|
||||
NOP IADD VI12,VI00,VI13
|
||||
NOP[E] IADD VI13,VI00,VI15
|
||||
NOP NOP
|
||||
NOP B Cnt
|
||||
NOP NOP
|
||||
|
||||
.EndMPG
|
||||
.EndDmaData
|
|
@ -0,0 +1,94 @@
|
|||
; Ambient light:
|
||||
NOP LQ VF26, ambientLight(VI00)
|
||||
NOP XITOP VI01
|
||||
NOP IADDIU VI03, VI12, 2
|
||||
Ambloop:
|
||||
NOP LQ VF03, 0(VI03) ; output color
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ITOF0 VF03, VF03 NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ADD.xyz VF03, VF03, VF26 NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
FTOI0 VF03, VF03 NOP
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP IADDIU VI03, VI03, numOutAttribs
|
||||
NOP IBNE VI01, VI00, Ambloop
|
||||
NOP SQ VF03, -numOutAttribs(VI03)
|
||||
; end amblight
|
||||
|
||||
; Direct Light
|
||||
NOP LQ VF26, lightDir(VI00)
|
||||
NOP XITOP VI01
|
||||
NOP XTOP VI02
|
||||
NOP IADDIU VI03, VI12, 2
|
||||
SUB.xyz VF26, VF00, VF26 NOP
|
||||
Dirloop:
|
||||
NOP LQ VF01, 3(VI02); ; normal
|
||||
NOP LQ VF02, 0(VI03); ; output color
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MUL VF03, VF01, VF26 NOP
|
||||
ITOF0 VF02, VF02 NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ADDy.x VF03, VF03, VF03y NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ADDz.x VF03, VF03, VF03z NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MAX.x VF03, VF00, VF03 NOP ; clamp to 0
|
||||
NOP[I] LOI 255
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MULi.x VF03, VF03, I NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ADDx.xyz VF02, VF02, VF03x NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
FTOI0 VF02, VF02 NOP
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP IADDIU VI02, VI02, numInAttribs
|
||||
NOP IADDIU VI03, VI03, numOutAttribs
|
||||
NOP IBNE VI01, VI00, Dirloop
|
||||
NOP SQ VF02, -numOutAttribs(VI03)
|
||||
; end dirlight
|
||||
|
||||
; Material color and clamp
|
||||
NOP LQ VF27, matColor(VI00)
|
||||
NOP XITOP VI01
|
||||
NOP IADDIU VI03, VI12, 2
|
||||
Colorloop:
|
||||
NOP LQ VF03, 0(VI03)
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
ITOF0 VF03, VF03 NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MUL VF03, VF03, VF27 NOP
|
||||
NOP[I] LOI 255
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
MINIi VF03, VF03, I NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
NOP NOP
|
||||
FTOI0 VF03, VF03 NOP
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP IADDIU VI03, VI03, numOutAttribs
|
||||
NOP IBNE VI01, VI00, Colorloop
|
||||
NOP SQ VF03, -numOutAttribs(VI03)
|
||||
; end material color
|
|
@ -0,0 +1,39 @@
|
|||
/* This is the the projection matrix we start with:
|
||||
* 1/2w 0 ox/2w + 1/2 -ox/2w
|
||||
* 0 -1/2h -oy/2h + 1/2 oy/2h
|
||||
* 0 0 1 0
|
||||
* 0 0 1 0
|
||||
* To get rid of the +1/2 in the combined matrix we
|
||||
* subtract the z-row/2 from the x- and y-rows.
|
||||
*
|
||||
* The z-row is then set to [0 0 0 1] such that multiplication
|
||||
* by XYZscale gives [0 0 0 zScale]. After perspective division
|
||||
* and addition of XYZoffset we then get zScale/w + zShift for z.
|
||||
*
|
||||
* XYZScale scales xy to the resolution and z by zScale.
|
||||
* XYZOffset translates xy to the GS coordinate system (where
|
||||
* [2048, 2048] is the center of the frame buffer) and add zShift to z.
|
||||
*/
|
||||
|
||||
; constant:
|
||||
; VF28-VF31 transformation matrix
|
||||
; VF25 XYZ offset
|
||||
|
||||
|
||||
SUB.z VF28, VF28, VF28 LOI 0.5 ; right.z = 0
|
||||
SUB.z VF29, VF29, VF29 LQ VF28, matrix(VI00) ; up.z = 0 - load matrix
|
||||
SUB.z VF30, VF30, VF30 LQ VF29, matrix+1(VI00) ; at.z = 0 - load matrix
|
||||
ADDw.z VF31, VF00, VF00 LQ VF30, matrix+2(VI00) ; at.z = 1 - load matrix
|
||||
NOP LQ VF31, matrix+3(VI00) ; - load matrix
|
||||
MULi.w VF20, VF28, I LQ.xyz VF01, XYZScale(VI00) ; fix matrix - load scale
|
||||
MULi.w VF21, VF29, I NOP ; fix matrix
|
||||
MULi.w VF22, VF30, I NOP ; fix matrix
|
||||
MULi.w VF23, VF31, I NOP ; fix matrix
|
||||
SUBw.xy VF28, VF28, VF20 NOP ; fix matrix
|
||||
SUBw.xy VF29, VF29, VF21 NOP ; fix matrix
|
||||
SUBw.xy VF30, VF30, VF22 NOP ; fix matrix
|
||||
SUBw.xy VF31, VF31, VF23 NOP ; fix matrix
|
||||
MUL.xy VF28, VF28, VF01 LQ.xyz VF25, XYZOffset(VI00) ; scale matrix
|
||||
MUL.xy VF29, VF29, VF01 IADDIU VI12, VI00, outBuf1 ; scale matrix
|
||||
MUL.xy VF30, VF30, VF01 IADDIU VI13, VI00, outBuf2 ; scale matrix
|
||||
MUL.xyz VF31, VF31, VF01 NOP ; scale matrix
|
|
@ -0,0 +1,94 @@
|
|||
.global skinPipe
|
||||
|
||||
.equ vertexTop, 0x2d0
|
||||
.equ numInAttribs, 5
|
||||
.equ numOutAttribs, 3
|
||||
.equ numOutBuf, 2
|
||||
.equ vertCount, ((vertexTop-numOutBuf)/(numInAttribs*2+numOutAttribs*numOutBuf))
|
||||
.equ offset, (vertCount*numInAttribs)
|
||||
.equ outBuf1, (2*offset)
|
||||
.equ outSize, ((vertexTop-outBuf1-2)/2)
|
||||
.equ outBuf2, (outBuf1+outSize)
|
||||
|
||||
.equ lightMat, 0x3d0
|
||||
.equ ambientLight, 0x3d4
|
||||
.equ lightDir, 0x3d5
|
||||
|
||||
.equ matrix, 0x3f0
|
||||
.equ XYZScale, 0x3f7
|
||||
.equ XYZOffset, 0x3f8
|
||||
.equ gifTag, 0x3fa
|
||||
.equ matColor, 0x3fb
|
||||
.equ surfProps, 0x3fc
|
||||
|
||||
|
||||
.balign 16,0
|
||||
skinPipe:
|
||||
DMAret *
|
||||
MPG 0, *
|
||||
.vu
|
||||
Start:
|
||||
#include "setup_persp.vu"
|
||||
Cnt:
|
||||
NOP XTOP VI02 ; input pointer
|
||||
NOP LQ VF01, gifTag(VI00)
|
||||
NOP XITOP VI01 ; vertex count
|
||||
NOP IADDIU VI05, VI00, 0x4000
|
||||
NOP IADD VI05, VI05, VI05
|
||||
NOP IOR VI05, VI05, VI01
|
||||
NOP SQ VF01, 0(VI12)
|
||||
NOP ISW.x VI05, 0(VI12)
|
||||
NOP IADDIU VI03, VI12, 1 ; output pointer
|
||||
NOP LQ VF18, lightMat(VI00)
|
||||
NOP LQ VF19, lightMat+1(VI00)
|
||||
NOP LQ VF20, lightMat+2(VI00)
|
||||
|
||||
Loop:
|
||||
NOP LQI VF01, (VI02++) ; vertex
|
||||
NOP LQI VF02, (VI02++) ; UV
|
||||
NOP LQI VF03, (VI02++) ; color
|
||||
NOP LQI VF04, (VI02++) ; normal
|
||||
NOP IADDIU VI02, VI02, 1 ; skip weights
|
||||
|
||||
MULAw.xyzw ACC, VF31, VF00w NOP ; transform vertex
|
||||
MADDAx.xyw ACC, VF28, VF01x NOP
|
||||
MADDAy.xyw ACC, VF29, VF01y NOP
|
||||
MADDz.xyzw VF01, VF30, VF01z NOP
|
||||
ITOF0 VF03, VF03 NOP
|
||||
ITOF0[I] VF04, VF04 LOI 0.0078125 ; - normal scale
|
||||
NOP NOP
|
||||
NOP DIV Q, VF00w, VF01w
|
||||
NOP WAITQ
|
||||
MULq VF01, VF01, Q NOP ; perspective division
|
||||
MULi VF04, VF04, I NOP ; scale normal
|
||||
NOP MR32.z VF02, VF00
|
||||
NOP NOP
|
||||
SUB.w VF01, VF01, VF01 NOP
|
||||
MULAx.xyz ACC, VF18, VF04x NOP ; transform normal
|
||||
MADDAy.xyz ACC, VF19, VF04y NOP
|
||||
MADDz.xyz VF04, VF20, VF04z NOP
|
||||
ADD.xyz VF01, VF01, VF25 NOP
|
||||
MULq VF02, VF02, Q NOP
|
||||
NOP NOP
|
||||
FTOI0 VF03, VF03 NOP
|
||||
FTOI4 VF01, VF01 NOP
|
||||
NOP SQ VF04, -2(VI02) ; store normal
|
||||
NOP IADDI VI01, VI01, -1
|
||||
NOP SQI VF02, (VI03++) ; STQ
|
||||
NOP SQI VF03, (VI03++) ; color
|
||||
NOP SQI VF01, (VI03++) ; vertex
|
||||
NOP IBNE VI01, VI00, Loop
|
||||
NOP NOP
|
||||
|
||||
#include "light.vu"
|
||||
|
||||
NOP XGKICK VI12
|
||||
NOP IADD VI15,VI00,VI12
|
||||
NOP IADD VI12,VI00,VI13
|
||||
NOP[E] IADD VI13,VI00,VI15
|
||||
NOP NOP
|
||||
NOP B Cnt
|
||||
NOP NOP
|
||||
|
||||
.EndMPG
|
||||
.EndDmaData
|
Loading…
Reference in New Issue