Merge branch 'master' of github.com:aap/librw

This commit is contained in:
aap 2017-08-21 14:40:23 +02:00
commit 0d8dc5d799
67 changed files with 5108 additions and 807 deletions

View File

@ -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
View File

@ -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"

184
skeleton/glfw.cpp Normal file
View File

@ -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

57
skeleton/skeleton.cpp Normal file
View File

@ -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;
}
}

91
skeleton/skeleton.h Normal file
View File

@ -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);

217
skeleton/win.cpp Normal file
View File

@ -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

43
src/base.cpp Normal file → Executable file
View File

@ -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

View File

@ -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")

75
src/camera.cpp Normal file → Executable file
View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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++;
}
}

View File

@ -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();

View File

@ -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++;
}
}

562
src/d3d/d3ddevice.cpp Executable file
View File

@ -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
}
}

View File

@ -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
}
}

70
src/d3d/d3drender.cpp Normal file
View File

@ -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
}
}

View File

@ -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

View File

@ -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();

View File

@ -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();

158
src/engine.cpp Normal file → Executable file
View File

@ -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
};
}
}

View File

@ -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)
{

View File

@ -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;

View File

@ -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"

View File

@ -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;
}

175
src/gl/gl3driver.cpp → src/gl/gl3device.cpp Normal file → Executable file
View File

@ -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
};
}
}

View File

@ -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--){

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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));
}

View File

@ -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"
;

View File

@ -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;

View File

@ -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"

View File

@ -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){

View File

@ -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"

View File

@ -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);

View File

@ -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"

View File

@ -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);
}
}

View File

@ -11,6 +11,8 @@
namespace rw {
PluginList Light::s_plglist = { sizeof(Light), sizeof(Light), nil, nil };
static void
lightSync(ObjectWithFrame*)
{

2
src/matfx.cpp Normal file → Executable file
View File

@ -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++)

1
src/pipeline.cpp Normal file → Executable file
View File

@ -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)))

1
src/ps2/pds.cpp Normal file → Executable file
View File

@ -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"

63
src/ps2/ps2.cpp Normal file → Executable file
View File

@ -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)
}
}
}
*/
}
}

41
src/ps2/ps2device.cpp Executable file
View File

@ -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

View File

@ -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();

50
src/ps2/rwps2.h Normal file → Executable file
View File

@ -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

View File

@ -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

89
src/rwengine.h Normal file → Executable file
View File

@ -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;
}
}

View File

@ -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)
}

52
src/rwobjects.h Normal file → Executable file
View File

@ -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;

View File

@ -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 };
}

2
src/rwplugins.h Normal file → Executable file
View File

@ -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);

9
src/world.cpp Normal file → Executable file
View File

@ -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();
}
}

134
tools/clumpview/camera.cpp Normal file
View File

@ -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;
}

26
tools/clumpview/camera.h Normal file
View File

@ -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);
};

181
tools/clumpview/main.cpp Normal file
View File

@ -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;
}

BIN
tools/clumpview/teapot.dff Normal file

Binary file not shown.

437
tools/ps2test/gs.h Executable file
View File

@ -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];
};

744
tools/ps2test/main.cpp Executable file
View File

@ -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;
}

95
tools/ps2test/mem.h Executable file
View File

@ -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)

23
tools/ps2test/ps2.h Executable file
View File

@ -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);

View File

@ -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

94
tools/ps2test/vu/light.vu Executable file
View File

@ -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

39
tools/ps2test/vu/setup_persp.vu Executable file
View File

@ -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

94
tools/ps2test/vu/skinpipe.dsm Executable file
View File

@ -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