3 * $Id: TaskIco.cpp 185 2006-10-22 22:30:10Z issei $
6 * Issei Suzuki <issei@issei.org> All rights reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
33 #include "PackfileManager.h"
34 #include "PackfileHandle.h"
35 #include "../tool/src/icodata/polyinfo.h"
36 #include "data/polyinfo.packh"
38 // TODO デバイス消失時に頂点バッファを作り直す
45 : public HsmEventBase<TaskIco, Event>
55 static Event CreateDraw() { return Event(NSIG_DRAW); }
56 static Event CreateExec() { return Event(NSIG_EXEC); }
57 static Event CreateLostDevice() { return Event(NSIG_LOST_DEVICE); }
58 static Event CreateResetDevice() { return Event(NSIG_RESET_DEVICE); }
61 Event(int nsig) : HsmEventBase(nsig) {}
63 friend class HsmEventBase<TaskIco, Event>;
70 , public HsmBase<TaskIco, Event>
75 virtual TASK_PRIO_TYPE getPrio() const { return TASK_PRIO_NORMAL; }
76 virtual TASK_DPRIO_TYPE getDPrio() const { return TASK_DPRIO_NORMAL; }
77 virtual void exec(ICtxTask& /*ctx*/, TASK_PRIO_TYPE prio);
78 virtual void draw(ICtxTask const& /*ctx*/, TASK_DPRIO_TYPE dprio) const;
79 virtual bool isTerminated() const { return HSM_ISIN(&TaskIco::_stateTerm); }
82 virtual void onLostDevice();
83 virtual void onResetDevice();
91 enum { D3DFVF_CUSTOMVERTEX = D3DFVF_XYZ | D3DFVF_NORMAL };
93 PackfileHandle<MEM_SEG_ICO> m_pack;
95 PolyVertList const* m_pPoly;
96 CComPtr<IDirect3DVertexBuffer9> m_spVtxBuf;
100 void _releaseModel();
101 void _setLight() const;
102 void _setCamera() const;
103 void _drawModel() const;
106 HsmState _stateMemAlloc(Event const& e);
107 HsmState _stateLoad(Event const& e);
108 HsmState _stateMain(Event const& e);
109 HsmState _stateTerm(Event const& e);
111 REF_COUNT_IMPL(TaskIco)
116 : HsmBase<TaskIco, Event>(&TaskIco::_stateLoad)
127 void TaskIco::exec(ICtxTask& /*ctx*/, TASK_PRIO_TYPE /*prio*/)
129 dispatchHsm(Event::CreateExec());
132 void TaskIco::draw(ICtxTask const& /*ctx*/, TASK_DPRIO_TYPE /*dprio*/) const
135 dbConsPrintf(_T("ICO App"));
136 const_cast<TaskIco*>(this)->dispatchHsm(Event::CreateDraw());
139 void TaskIco::onLostDevice()
141 dispatchHsm(Event::CreateLostDevice());
144 void TaskIco::onResetDevice()
146 dispatchHsm(Event::CreateResetDevice());
149 bool TaskIco::_initModel()
151 PolyVertList const* pPoly = NULL;
152 m_pack.getResIdx(&pPoly, 1);
154 CComPtr<IDirect3DVertexBuffer9> spVtxBuf;
155 HRESULT hr = g_d3ddev.CreateVertexBuffer(
156 static_cast<UINT>(sizeof(PolyVertList::CustomVertex) * pPoly->vertex_count),
165 void* pVtxBuf = NULL;
166 hr = spVtxBuf->Lock(0, 0, &pVtxBuf, 0);
169 ::memcpy(pVtxBuf, pPoly->vertex_list, sizeof(PolyVertList::CustomVertex) * pPoly->vertex_count);
173 m_spVtxBuf = spVtxBuf;
178 void TaskIco::_releaseModel()
181 m_spVtxBuf.Release();
185 void TaskIco::_setLight() const
189 ::ZeroMemory(&light, sizeof(light));
190 light.Type = D3DLIGHT_DIRECTIONAL;
191 light.Diffuse.r = 0.8f;
192 light.Diffuse.g = 0.8f;
193 light.Diffuse.b = 0.8f;
194 D3DXVECTOR3 vecDir(-1.0f, +1.0f, -5.0f);
195 D3DXVec3Normalize(reinterpret_cast<D3DXVECTOR3*>(&light.Direction), &vecDir);
197 g_d3ddev.SetLight(0, &light);
198 g_d3ddev.LightEnable(0, TRUE);
199 g_d3ddev.SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(64, 64, 64));
200 g_d3ddev.SetRenderState(D3DRS_LIGHTING, TRUE);
203 void TaskIco::_setCamera() const
206 static D3DXVECTOR3 const vecViewEye (0.0f, 3.0f,-5.0f);
207 static D3DXVECTOR3 const vecViewLookAt (0.0f, 0.0f, 0.0f);
208 static D3DXVECTOR3 const vecViewUp (0.0f, 1.0f, 0.0f);
210 D3DXMatrixLookAtLH(&matView, &vecViewEye, &vecViewLookAt, &vecViewUp);
211 g_d3ddev.SetTransform(D3DTS_VIEW, &matView);
215 D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);
216 g_d3ddev.SetTransform(D3DTS_PROJECTION, &matProj);
219 void TaskIco::_drawModel() const
221 g_d3ddev.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // TODO
222 g_d3ddev.SetRenderState(D3DRS_ZENABLE, TRUE);
223 g_d3ddev.SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
226 D3DXMatrixIdentity(&matWorld);
227 D3DXMatrixRotationY(&matWorld, m_fAngle);
228 g_d3ddev.SetTransform(D3DTS_WORLD, &matWorld);
231 ::ZeroMemory(&mtrl, sizeof(mtrl));
232 mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
233 mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
234 mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
235 mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
236 g_d3ddev.SetMaterial(&mtrl);
238 g_d3ddev.SetStreamSource(0, m_spVtxBuf, 0, sizeof(PolyVertList::CustomVertex));
239 g_d3ddev.SetFVF(D3DFVF_CUSTOMVERTEX);
240 for (PolyVertList::IndexRange const* p = m_pPoly->index_list; p->count > 0; ++p)
241 g_d3ddev.DrawPrimitive(D3DPT_TRIANGLEFAN, p->first, p->count);
244 TaskIco::HsmState TaskIco::_stateMemAlloc(Event const& e)
246 switch (e.getSignal()) {
247 case Event::NSIG_ENTER:
248 g_pack.createSegment(MEM_SEG_ICO, MEM_SEG_ICO_SIZE);
250 case Event::NSIG_EXIT:
252 g_pack.breakSegment(MEM_SEG_ICO);
259 TaskIco::HsmState TaskIco::_stateLoad(Event const& e)
261 switch (e.getSignal()) {
262 case Event::NSIG_ENTER:
263 m_pack.load(POLYINFO_PACK);
265 case Event::NSIG_EXEC:
267 if (m_pack.isLoaded())
268 HSM_TRAN(&TaskIco::_stateMain);
270 case Event::NSIG_DRAW:
272 dbConsPrintf(_T("loading .. %d"), m_load_count);
275 return &TaskIco::_stateMemAlloc;
278 TaskIco::HsmState TaskIco::_stateMain(Event const& e)
280 switch (e.getSignal()) {
281 case Event::NSIG_ENTER:
282 case Event::NSIG_RESET_DEVICE:
285 case Event::NSIG_EXIT:
286 case Event::NSIG_LOST_DEVICE:
289 case Event::NSIG_EXEC:
290 // XXX failed to load
292 HSM_TRAN(&TaskIco::_stateTerm);
294 m_fAngle += D3DX_PI / EXEC_PER_SEC;
295 if ((padGetRep() & (PAD_SE | PAD_ST)) == (PAD_SE | PAD_ST))
296 HSM_TRAN(&TaskIco::_stateTerm);
298 case Event::NSIG_DRAW:
303 dbConsPrintf(_T("Keep pushing SELECT & START to exit"));
306 return &TaskIco::_stateMemAlloc;
309 TaskIco::HsmState TaskIco::_stateTerm(Event const& /*e*/)
314 boost::intrusive_ptr<ITask> CreateTaskIco()
316 return boost::intrusive_ptr<ITask>(new TaskIco, false);