00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "Core/precomp.h"
00016
00017 #include <API/Display/Display/display.h>
00018 #include <API/Display/Display/displaycard.h>
00019 #include <API/Display/Display/surface.h>
00020 #include <Display/Display/Generic/displaycard_generic.h>
00021 #include <Display/Display/Generic/surface_generic.h>
00022 #include <Display/Display/Generic/restype_surface.h>
00023 #include <Display/Display/Generic/blit_dynamic.h>
00024 #include "cardsurface_blitter.h"
00025 #include "colormap.h"
00026 #include "blit_macros.h"
00027
00028 extern "C"
00029 {
00030 #include <Hermes/H_Conv.h>
00031 #include <Hermes/H_Pal.h>
00032 }
00033
00034 CL_Surface_Generic::CL_Surface_Generic(
00035 CL_SurfaceProvider *_provider,
00036 bool _delete_provider,
00037 bool _dynamic,
00038 CL_Resource *_resource)
00039 {
00040 resource = _resource;
00041 ref_count = 0;
00042 provider = _provider;
00043 delete_provider = _delete_provider;
00044 translate_x = 0;
00045 translate_y = 0;
00046 dynamic = _dynamic;
00047
00048 provider->lock();
00049 width = provider->get_width();
00050 height = provider->get_height();
00051 no_sprs = provider->get_num_frames();
00052 translate_x = provider->get_translate_offset_x();
00053 translate_y = provider->get_translate_offset_y();
00054 provider->unlock();
00055
00056 card_surfaces = new CL_CardSurface*[CL_Display::cards.size()];
00057
00058 int num_cards = CL_Display::cards.size();
00059 for (int i=0; i<num_cards; i++)
00060 {
00061 card_surfaces[i] = NULL;
00062 }
00063 }
00064
00065 CL_Surface_Generic::~CL_Surface_Generic()
00066 {
00067 int num_cards = CL_Display::cards.size();
00068 for (int i=0; i<num_cards; i++) delete card_surfaces[i];
00069 delete[] card_surfaces;
00070
00071 if (delete_provider == true) delete provider;
00072 }
00073
00074 int CL_Surface_Generic::add_reference()
00075 {
00076 if (ref_count > 0 && resource != NULL) resource->load();
00077 return ++ref_count;
00078 }
00079
00080 int CL_Surface_Generic::release_reference()
00081 {
00082 if (resource != NULL) resource->unload();
00083 return --ref_count;
00084 }
00085
00086 inline int CL_Surface_Generic::ensure_surface_prepared(CL_DisplayCard *card)
00087 {
00088 int card_no = card == NULL ? CL_Display::get_current_card()->get_card_no() : card->get_card_no();
00089 if (card_surfaces[card_no] == NULL)
00090 {
00091 provider->lock();
00092
00093 translate_x = provider->get_translate_x();
00094 translate_y = provider->get_translate_y();
00095
00096 width = provider->get_width();
00097 height = provider->get_height();
00098 no_sprs = provider->get_num_frames();
00099
00100 CL_DisplayCard_Generic *gen = ((CL_DisplayCard_Generic *) CL_Display::cards[card_no]);
00101 if (dynamic)
00102 {
00103 card_surfaces[card_no] = new CL_CardSurface_Blitter(gen, provider, true);
00104 }
00105 else
00106 {
00107 card_surfaces[card_no] = gen->create_cardsurface_video(provider);
00108 if (card_surfaces[card_no] == NULL) card_surfaces[card_no] = gen->create_cardsurface_system(provider);
00109 }
00110
00111 provider->unlock();
00112 }
00113
00114 return card_no;
00115 }
00116
00117 CL_CardSurface *CL_Surface_Generic::get_cardsurface(int surface_num)
00118 {
00119 return card_surfaces[ensure_surface_prepared(CL_Display::cards[surface_num])];
00120 }
00121
00122 CL_CardSurface *CL_Surface_Generic::get_cardsurface(CL_DisplayCard *card)
00123 {
00124 return card_surfaces[ensure_surface_prepared(card)];
00125 }
00126
00127 void CL_Surface_Generic::flush(CL_DisplayCard *card)
00128 {
00129 if (card == NULL)
00130 {
00131 delete card_surfaces[CL_Display::get_current_card()->get_card_no()];
00132 card_surfaces[CL_Display::get_current_card()->get_card_no()] = NULL;
00133 }
00134 else
00135 {
00136 delete card_surfaces[card->get_card_no()];
00137 card_surfaces[card->get_card_no()] = NULL;
00138 }
00139 }
00140
00141 void CL_Surface_Generic::reload()
00142 {
00143 bool provider_locked = false;
00144
00145 int num_cards = CL_Display::cards.size();
00146 for (int i=0; i<num_cards; i++)
00147 {
00148 if (card_surfaces[i] != NULL)
00149 {
00150 if (!provider_locked)
00151 {
00152 provider->lock();
00153 translate_x = provider->get_translate_x();
00154 translate_y = provider->get_translate_y();
00155
00156 width = provider->get_width();
00157 height = provider->get_height();
00158 no_sprs = provider->get_num_frames();
00159
00160 provider_locked = true;
00161 }
00162 card_surfaces[i]->reload();
00163 }
00164 }
00165
00166 if (provider_locked) provider->unlock();
00167 }
00168
00169 bool CL_Surface_Generic::is_video(CL_DisplayCard *card) const
00170 {
00171 int card_no = card == NULL ? CL_Display::get_current_card()->get_card_no() : card->get_card_no();
00172
00173 return card_surfaces[card_no] != NULL && card_surfaces[card_no]->is_video();
00174 }
00175
00176 bool CL_Surface_Generic::is_loaded(CL_DisplayCard *card) const
00177 {
00178 int card_no = card == NULL ? CL_Display::get_current_card()->get_card_no() : card->get_card_no();
00179
00180 return card_surfaces[card_no] != NULL;
00181 }
00182
00183 bool CL_Surface_Generic::convert_video(CL_DisplayCard *card)
00184 {
00185 if (dynamic) return false;
00186
00187 int card_no = card == NULL ? CL_Display::get_current_card()->get_card_no() : card->get_card_no();
00188
00189 translate_x = provider->get_translate_x();
00190 translate_y = provider->get_translate_y();
00191
00192 width = provider->get_width();
00193 height = provider->get_height();
00194 no_sprs = provider->get_num_frames();
00195
00196 if (card_surfaces[card_no] == NULL)
00197 {
00198 CL_DisplayCard_Generic *gen = ((CL_DisplayCard_Generic *) CL_Display::cards[card_no]);
00199 card_surfaces[card_no] = gen->create_cardsurface_video(provider);
00200
00201 if (card_surfaces[card_no] == NULL) return false;
00202 }
00203 else
00204 {
00205 if (card_surfaces[card_no]->is_video()) return true;
00206
00207 if (card_surfaces[card_no]->can_convert_video())
00208 {
00209 return card_surfaces[card_no]->convert_video();
00210 }
00211 else
00212 {
00213 return false;
00214 }
00215 }
00216 return true;
00217 }
00218
00219 bool CL_Surface_Generic::convert_system(CL_DisplayCard *card)
00220 {
00221 if (dynamic) return true;
00222
00223 int card_no = card == NULL ? CL_Display::get_current_card()->get_card_no() : card->get_card_no();
00224
00225 if (card_surfaces[card_no] == NULL)
00226 {
00227 CL_DisplayCard_Generic *gen = ((CL_DisplayCard_Generic *) CL_Display::cards[card_no]);
00228 card_surfaces[card_no] = gen->create_cardsurface_system(provider);
00229
00230 if (card_surfaces[card_no] == NULL) return false;
00231 }
00232 else
00233 {
00234 if (!card_surfaces[card_no]->is_video()) return true;
00235
00236 if (card_surfaces[card_no]->can_convert_system())
00237 {
00238 return card_surfaces[card_no]->convert_system();
00239 }
00240 else
00241 {
00242 return false;
00243 }
00244 }
00245 return true;
00246 }
00247
00248 CL_SurfaceProvider *CL_Surface_Generic::get_provider() const
00249 {
00250 return provider;
00251 }
00252
00253 void CL_Surface_Generic::put_screen(
00254 int x,
00255 int y,
00256 int spr_no,
00257 CL_DisplayCard *card)
00258 {
00259 card_surfaces[ensure_surface_prepared(card)]->put_screen(
00260 x+translate_x,
00261 y+translate_y,
00262 spr_no,
00263 NULL);
00264 }
00265
00266 void CL_Surface_Generic::put_screen(
00267 int x,
00268 int y,
00269 float scale_x,
00270 float scale_y,
00271 int spr_no,
00272 CL_DisplayCard *card)
00273 {
00274 card_surfaces[ensure_surface_prepared(card)]->put_screen(
00275 x+translate_x,
00276 y+translate_y,
00277 scale_x,
00278 scale_y,
00279 spr_no,
00280 NULL);
00281 }
00282
00283 void CL_Surface_Generic::put_screen(
00284 int x,
00285 int y,
00286 int size_x,
00287 int size_y,
00288 int spr_no,
00289 CL_DisplayCard *card)
00290 {
00291 card_surfaces[ensure_surface_prepared(card)]->put_screen(
00292 x+translate_x,
00293 y+translate_y,
00294 size_x,
00295 size_y,
00296 spr_no,
00297 NULL);
00298 }
00299
00300 void CL_Surface_Generic::put_target(
00301 int x,
00302 int y,
00303 int spr_no,
00304 CL_Target *target)
00305 {
00306 CL_Blit_Dynamic blitter(provider, target);
00307
00308
00309 CL_ClipRect t_cliprect = target->get_clip_rect();
00310 CL_ClipRect s_cliprect(x, y, provider->get_width()+x, provider->get_height()+y);
00311
00312
00313
00314 if (t_cliprect.test_clipped(s_cliprect))
00315 {
00316 s_cliprect = t_cliprect.clip(s_cliprect);
00317
00318 blitter.blt_clip(
00319 target,
00320 x,
00321 y,
00322 spr_no,
00323 s_cliprect);
00324 }
00325 else
00326 {
00327 blitter.blt_noclip(
00328 target,
00329 x,
00330 y,
00331 spr_no);
00332 }
00333 }