IDirect3DRM IDirect3DRM_iface;
IDirect3DRM2 IDirect3DRM2_iface;
IDirect3DRM3 IDirect3DRM3_iface;
- LONG ref;
+ LONG ref1, ref2, ref3, iface_count;
};
static inline struct d3drm *impl_from_IDirect3DRM(IDirect3DRM *iface)
return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM3_iface);
}
+static void d3drm_destroy(struct d3drm *d3drm)
+{
+ HeapFree(GetProcessHeap(), 0, d3drm);
+ TRACE("d3drm object %p is being destroyed.\n", d3drm);
+}
+
static HRESULT WINAPI d3drm1_QueryInterface(IDirect3DRM *iface, REFIID riid, void **out)
{
struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
else
{
*out = NULL;
- WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
- return E_NOINTERFACE;
+ WARN("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(riid));
+ return CLASS_E_CLASSNOTAVAILABLE;
}
IUnknown_AddRef((IUnknown *)*out);
static ULONG WINAPI d3drm1_AddRef(IDirect3DRM *iface)
{
struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
- ULONG refcount = InterlockedIncrement(&d3drm->ref);
+ ULONG refcount = InterlockedIncrement(&d3drm->ref1);
TRACE("%p increasing refcount to %u.\n", iface, refcount);
+ if (refcount == 1)
+ InterlockedIncrement(&d3drm->iface_count);
+
return refcount;
}
static ULONG WINAPI d3drm1_Release(IDirect3DRM *iface)
{
struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
- ULONG refcount = InterlockedDecrement(&d3drm->ref);
+ ULONG refcount = InterlockedDecrement(&d3drm->ref1);
TRACE("%p decreasing refcount to %u.\n", iface, refcount);
- if (!refcount)
- HeapFree(GetProcessHeap(), 0, d3drm);
+ if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
+ d3drm_destroy(d3drm);
return refcount;
}
static HRESULT WINAPI d3drm1_CreateDevice(IDirect3DRM *iface,
DWORD width, DWORD height, IDirect3DRMDevice **device)
{
+ struct d3drm_device *object;
+ HRESULT hr;
FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown **)device);
+ hr = d3drm_device_create(&object);
+ if (FAILED(hr))
+ return hr;
+
+ *device = IDirect3DRMDevice_from_impl(object);
+
+ return D3DRM_OK;
}
static HRESULT WINAPI d3drm1_CreateDeviceFromSurface(IDirect3DRM *iface, GUID *guid,
IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice **device)
{
- FIXME("iface %p, guid %s, ddraw %p, backbuffer %p, device %p partial stub.\n",
+ struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
+ struct d3drm_device *object;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
iface, debugstr_guid(guid), ddraw, backbuffer, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown **)device);
+ if (!device)
+ return D3DRMERR_BADVALUE;
+ *device = NULL;
+
+ if (!backbuffer || !ddraw)
+ return D3DRMERR_BADDEVICE;
+
+ hr = d3drm_device_create(&object);
+ if (FAILED(hr))
+ return hr;
+
+ hr = d3drm_device_init(object, 1, &d3drm->IDirect3DRM_iface, ddraw, backbuffer, TRUE);
+ if (SUCCEEDED(hr))
+ *device = IDirect3DRMDevice_from_impl(object);
+ else
+ d3drm_device_destroy(object);
+
+ return hr;
}
static HRESULT WINAPI d3drm1_CreateDeviceFromD3D(IDirect3DRM *iface,
IDirect3D *d3d, IDirect3DDevice *d3d_device, IDirect3DRMDevice **device)
{
- FIXME("iface %p, d3d %p, d3d_device %p, device %p partial stub.\n",
+ struct d3drm_device *object;
+ HRESULT hr;
+ TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
iface, d3d, d3d_device, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown **)device);
+ if (!device)
+ return D3DRMERR_BADVALUE;
+ *device = NULL;
+ if (!d3d || !d3d_device)
+ return D3DRMERR_BADVALUE;
+
+ hr = d3drm_device_create(&object);
+ if (FAILED(hr))
+ return hr;
+
+ hr = d3drm_device_set_ddraw_device_d3d(object, iface, d3d, d3d_device);
+ if (FAILED(hr))
+ {
+ d3drm_device_destroy(object);
+ return hr;
+ }
+ *device = IDirect3DRMDevice_from_impl(object);
+
+ return D3DRM_OK;
}
static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
IDirectDrawClipper *clipper, GUID *guid, int width, int height,
IDirect3DRMDevice **device)
{
- FIXME("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
+ struct d3drm_device *object;
+ IDirectDraw *ddraw;
+ IDirectDrawSurface *render_target;
+ HRESULT hr;
+
+ TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
iface, clipper, debugstr_guid(guid), width, height, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown **)device);
+ if (!device)
+ return D3DRMERR_BADVALUE;
+ *device = NULL;
+
+ if (!clipper || !width || !height)
+ return D3DRMERR_BADVALUE;
+
+ hr = DirectDrawCreate(NULL, &ddraw, NULL);
+ if (FAILED(hr))
+ return hr;
+
+ hr = d3drm_device_create(&object);
+ if (FAILED(hr))
+ {
+ IDirectDraw_Release(ddraw);
+ return hr;
+ }
+
+ hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
+ if (FAILED(hr))
+ {
+ IDirectDraw_Release(ddraw);
+ d3drm_device_destroy(object);
+ return hr;
+ }
+
+ hr = d3drm_device_init(object, 1, iface, ddraw, render_target, TRUE);
+ IDirectDraw_Release(ddraw);
+ IDirectDrawSurface_Release(render_target);
+ if (FAILED(hr))
+ d3drm_device_destroy(object);
+ else
+ *device = IDirect3DRMDevice_from_impl(object);
+
+ return hr;
}
static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
static ULONG WINAPI d3drm2_AddRef(IDirect3DRM2 *iface)
{
struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
+ ULONG refcount = InterlockedIncrement(&d3drm->ref2);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
+
+ if (refcount == 1)
+ InterlockedIncrement(&d3drm->iface_count);
- return d3drm1_AddRef(&d3drm->IDirect3DRM_iface);
+ return refcount;
}
static ULONG WINAPI d3drm2_Release(IDirect3DRM2 *iface)
{
struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
+ ULONG refcount = InterlockedDecrement(&d3drm->ref2);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
+
+ if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
+ d3drm_destroy(d3drm);
- return d3drm1_Release(&d3drm->IDirect3DRM_iface);
+ return refcount;
}
static HRESULT WINAPI d3drm2_CreateObject(IDirect3DRM2 *iface,
static HRESULT WINAPI d3drm2_CreateDevice(IDirect3DRM2 *iface,
DWORD width, DWORD height, IDirect3DRMDevice2 **device)
{
- FIXME("iface %p, width %u, height %u, device %p.\n", iface, width, height, device);
+ struct d3drm_device *object;
+ HRESULT hr;
+ FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
+
+ hr = d3drm_device_create(&object);
+ if (FAILED(hr))
+ return hr;
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice2, (IUnknown **)device);
+ *device = IDirect3DRMDevice2_from_impl(object);
+
+ return D3DRM_OK;
}
static HRESULT WINAPI d3drm2_CreateDeviceFromSurface(IDirect3DRM2 *iface, GUID *guid,
IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice2 **device)
{
- FIXME("iface %p, guid %s, ddraw %p, backbuffer %p, device %p partial stub.\n",
+ struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
+ IDirect3DRMDevice3 *device3;
+ HRESULT hr;
+ TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
iface, debugstr_guid(guid), ddraw, backbuffer, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice2, (IUnknown **)device);
+ if (!device)
+ return D3DRMERR_BADVALUE;
+ *device = NULL;
+ hr = IDirect3DRM3_CreateDeviceFromSurface(&d3drm->IDirect3DRM3_iface, guid, ddraw, backbuffer, 0, &device3);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
+ IDirect3DRMDevice3_Release(device3);
+
+ return hr;
}
static HRESULT WINAPI d3drm2_CreateDeviceFromD3D(IDirect3DRM2 *iface,
- IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice2 **device)
+ IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice2 **device)
{
- FIXME("iface %p, d3d %p, d3d_device %p, device %p partial stub.\n",
+ struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
+ IDirect3D *d3d1;
+ IDirect3DDevice *d3d_device1;
+ IDirect3DRMDevice *device1;
+ HRESULT hr;
+ TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
iface, d3d, d3d_device, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice2, (IUnknown **)device);
+ if (!device)
+ return D3DRMERR_BADVALUE;
+ *device = NULL;
+ if (!d3d || !d3d_device)
+ return D3DRMERR_BADVALUE;
+
+ hr = IDirect3D2_QueryInterface(d3d, &IID_IDirect3D, (void **)&d3d1);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IDirect3DDevice2_QueryInterface(d3d_device, &IID_IDirect3DDevice, (void **)&d3d_device1);
+ if (FAILED(hr))
+ {
+ IDirect3D_Release(d3d1);
+ return hr;
+ }
+
+ hr = IDirect3DRM_CreateDeviceFromD3D(&d3drm->IDirect3DRM_iface, d3d1, d3d_device1, &device1);
+ IDirect3D_Release(d3d1);
+ IDirect3DDevice_Release(d3d_device1);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice2, (void **)device);
+ IDirect3DRMDevice_Release(device1);
+
+ return hr;
}
static HRESULT WINAPI d3drm2_CreateDeviceFromClipper(IDirect3DRM2 *iface,
IDirectDrawClipper *clipper, GUID *guid, int width, int height,
IDirect3DRMDevice2 **device)
{
- FIXME("iface %p, clipper %p, guid %s, width %d, height %d, device %p partial stub.\n",
+ struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
+ IDirect3DRMDevice3 *device3;
+ HRESULT hr;
+
+ TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
iface, clipper, debugstr_guid(guid), width, height, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice2, (IUnknown **)device);
+ if (!device)
+ return D3DRMERR_BADVALUE;
+ *device = NULL;
+ hr = IDirect3DRM3_CreateDeviceFromClipper(&d3drm->IDirect3DRM3_iface, clipper, guid, width, height, &device3);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
+ IDirect3DRMDevice3_Release(device3);
+
+ return hr;
}
static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface,
static ULONG WINAPI d3drm3_AddRef(IDirect3DRM3 *iface)
{
struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
+ ULONG refcount = InterlockedIncrement(&d3drm->ref3);
+
+ TRACE("%p increasing refcount to %u.\n", iface, refcount);
- return d3drm1_AddRef(&d3drm->IDirect3DRM_iface);
+ if (refcount == 1)
+ InterlockedIncrement(&d3drm->iface_count);
+
+ return refcount;
}
static ULONG WINAPI d3drm3_Release(IDirect3DRM3 *iface)
{
struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
+ ULONG refcount = InterlockedDecrement(&d3drm->ref3);
+
+ TRACE("%p decreasing refcount to %u.\n", iface, refcount);
- return d3drm1_Release(&d3drm->IDirect3DRM_iface);
+ if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
+ d3drm_destroy(d3drm);
+
+ return refcount;
}
static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface,
static HRESULT WINAPI d3drm3_CreateDevice(IDirect3DRM3 *iface,
DWORD width, DWORD height, IDirect3DRMDevice3 **device)
{
+ struct d3drm_device *object;
+ HRESULT hr;
FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown **)device);
+ hr = d3drm_device_create(&object);
+ if (FAILED(hr))
+ return hr;
+
+ *device = IDirect3DRMDevice3_from_impl(object);
+
+ return D3DRM_OK;
}
static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *guid,
- IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice3 **device)
+ IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, DWORD flags, IDirect3DRMDevice3 **device)
{
- FIXME("iface %p, guid %s, ddraw %p, backbuffer %p, device %p partial stub.\n",
- iface, debugstr_guid(guid), ddraw, backbuffer, device);
+ struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
+ struct d3drm_device *object;
+ BOOL use_z_surface;
+ HRESULT hr;
+
+ TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, flags %#x, device %p.\n",
+ iface, debugstr_guid(guid), ddraw, backbuffer, flags, device);
+
+ if (!device)
+ return D3DRMERR_BADVALUE;
+ *device = NULL;
+
+ if (!backbuffer || !ddraw)
+ return D3DRMERR_BADDEVICE;
+
+ hr = d3drm_device_create(&object);
+ if (FAILED(hr))
+ return hr;
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown **)device);
+ use_z_surface = !(flags & D3DRMDEVICE_NOZBUFFER);
+
+ hr = d3drm_device_init(object, 3, &d3drm->IDirect3DRM_iface, ddraw, backbuffer, use_z_surface);
+ if (SUCCEEDED(hr))
+ *device = IDirect3DRMDevice3_from_impl(object);
+ else
+ d3drm_device_destroy(object);
+
+ return hr;
}
static HRESULT WINAPI d3drm3_CreateDeviceFromD3D(IDirect3DRM3 *iface,
IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice3 **device)
{
- FIXME("iface %p, d3d %p, d3d_device %p, device %p partial stub.\n",
+ struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
+ IDirect3D *d3d1;
+ IDirect3DDevice *d3d_device1;
+ IDirect3DRMDevice *device1;
+ HRESULT hr;
+ TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
iface, d3d, d3d_device, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown **)device);
+ if (!device)
+ return D3DRMERR_BADVALUE;
+ *device = NULL;
+ if (!d3d || !d3d_device)
+ return D3DRMERR_BADVALUE;
+
+ hr = IDirect3D2_QueryInterface(d3d, &IID_IDirect3D, (void **)&d3d1);
+ if (FAILED(hr))
+ return hr;
+ hr = IDirect3DDevice2_QueryInterface(d3d_device, &IID_IDirect3DDevice, (void **)&d3d_device1);
+ if (FAILED(hr))
+ {
+ IDirect3D_Release(d3d1);
+ return hr;
+ }
+
+ hr = IDirect3DRM_CreateDeviceFromD3D(&d3drm->IDirect3DRM_iface, d3d1, d3d_device1, &device1);
+ IDirect3D_Release(d3d1);
+ IDirect3DDevice_Release(d3d_device1);
+ if (FAILED(hr))
+ return hr;
+
+ hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice3, (void **)device);
+ IDirect3DRMDevice_Release(device1);
+
+ return hr;
}
static HRESULT WINAPI d3drm3_CreateDeviceFromClipper(IDirect3DRM3 *iface,
IDirectDrawClipper *clipper, GUID *guid, int width, int height,
IDirect3DRMDevice3 **device)
{
- FIXME("iface %p, clipper %p, guid %s, width %d, height %d, device %p partial stub.\n",
+ struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
+ struct d3drm_device *object;
+ IDirectDraw *ddraw;
+ IDirectDrawSurface *render_target;
+ HRESULT hr;
+
+ TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
iface, clipper, debugstr_guid(guid), width, height, device);
- return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown **)device);
+ if (!device)
+ return D3DRMERR_BADVALUE;
+ *device = NULL;
+
+ if (!clipper || !width || !height)
+ return D3DRMERR_BADVALUE;
+
+ hr = DirectDrawCreate(NULL, &ddraw, NULL);
+ if (FAILED(hr))
+ return hr;
+
+ hr = d3drm_device_create(&object);
+ if (FAILED(hr))
+ {
+ IDirectDraw_Release(ddraw);
+ return hr;
+ }
+
+ hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
+ if (FAILED(hr))
+ {
+ IDirectDraw_Release(ddraw);
+ d3drm_device_destroy(object);
+ return hr;
+ }
+
+ hr = d3drm_device_init(object, 3, &d3drm->IDirect3DRM_iface, ddraw, render_target, TRUE);
+ IDirectDraw_Release(ddraw);
+ IDirectDrawSurface_Release(render_target);
+ if (FAILED(hr))
+ d3drm_device_destroy(object);
+ else
+ *device = IDirect3DRMDevice3_from_impl(object);
+
+ return hr;
}
static HRESULT WINAPI d3drm3_CreateShadow(IDirect3DRM3 *iface, IUnknown *object, IDirect3DRMLight *light,
IDirectXFileDataReference *reference;
IDirectXFileBinary *binary;
- hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileBinary, (void **)&binary);
- if (SUCCEEDED(hr))
+ if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
+ &IID_IDirectXFileBinary, (void **)&binary)))
{
FIXME("Binary Object not supported yet\n");
IDirectXFileBinary_Release(binary);
- continue;
}
-
- hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileData, (void **)&data);
- if (SUCCEEDED(hr))
+ else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
+ &IID_IDirectXFileData, (void **)&data)))
{
TRACE("Found Data Object\n");
hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
IDirectXFileData_Release(data);
- continue;
}
- hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileDataReference, (void **)&reference);
- if (SUCCEEDED(hr))
+ else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
+ &IID_IDirectXFileDataReference, (void **)&reference)))
{
TRACE("Found Data Object Reference\n");
IDirectXFileDataReference_Resolve(reference, &data);
hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
IDirectXFileData_Release(data);
IDirectXFileDataReference_Release(reference);
- continue;
}
+ IDirectXFileObject_Release(child);
}
if (hr != DXFILEERR_NOMOREOBJECTS)
/* Cannot be requested */
if (parent_frame)
{
- D3DRMMATRIX4D matrix;
+ D3DRMMATRIX4D *matrix;
DWORD size;
TRACE("Load Frame Transform Matrix data\n");
- size = sizeof(matrix);
- hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)matrix);
+ hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)&matrix);
if ((hr != DXFILE_OK) || (size != sizeof(matrix)))
goto end;
- hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, matrix);
+ hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, *matrix);
if (FAILED(hr))
goto end;
}
object->IDirect3DRM_iface.lpVtbl = &d3drm1_vtbl;
object->IDirect3DRM2_iface.lpVtbl = &d3drm2_vtbl;
object->IDirect3DRM3_iface.lpVtbl = &d3drm3_vtbl;
- object->ref = 1;
+ object->ref1 = 1;
+ object->iface_count = 1;
*d3drm = &object->IDirect3DRM_iface;
return S_OK;
}
+
+HRESULT WINAPI DllCanUnloadNow(void)
+{
+ return S_FALSE;
+}
+
+HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
+{
+ TRACE("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+
+ if(!ppv)
+ return E_INVALIDARG;
+
+ return CLASS_E_CLASSNOTAVAILABLE;
+}