1 /* Mednafen - Multi-system Emulator
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17 
18 // Code for drawing save states and mooovies
19 // all functions should be called from the main thread
20 #include "main.h"
21 #include "video.h"
22 #include <string.h>
23 #include <trio/trio.h>
24 
25 static MDFN_Surface *PreviewSurface = NULL, *TextSurface = NULL;
26 static MDFN_Rect PreviewRect, TextRect;
27 
28 static StateStatusStruct *StateStatus;
29 static uint32 StateShow;
30 static bool IsMovie;
31 
DrawStateMovieRow(MDFN_Surface * surface,int * nstatus,int cur,int recently_saved,const char * text)32 void DrawStateMovieRow(MDFN_Surface *surface, int *nstatus, int cur, int recently_saved, const char *text)
33 {
34  MDFN_DrawFillRect(surface, 0, 0, 230, 40, surface->MakeColor(0x00, 0x00, 0x00, 170));
35 
36  // nstatus
37  for(int i = 1; i < 11; i++)
38  {
39   char stringie[2];
40   uint32 bordercol;
41   uint32 rect_bg_color = surface->MakeColor(0x00, 0x00, 0x00, 0xFF);
42 
43   if(cur == (i % 10))
44    bordercol = surface->MakeColor(0x60, 0x20, 0xb0, 0xFF);
45   else
46    bordercol = surface->MakeColor(0, 0, 0, 0xFF);
47 
48   stringie[0] = '0' + (i % 10);
49   stringie[1] = 0;
50 
51   if(nstatus[i % 10])
52   {
53    rect_bg_color = surface->MakeColor(0x00, 0x38, 0x28, 0xFF);
54 
55    if(recently_saved == (i % 10))
56     rect_bg_color = surface->MakeColor(0x48, 0x00, 0x34, 0xFF);
57   }
58 
59   MDFN_DrawFillRect(surface, (i - 1) * 23, 0, 23, 18 + 1, bordercol, rect_bg_color);
60 
61   DrawTextShadow(surface, (i - 1) * 23 + 7, 0, stringie, surface->MakeColor(0xE0, 0xFF, 0xE0, 0xFF), surface->MakeColor(0x00, 0x00, 0x00, 0xFF), MDFN_FONT_9x18_18x18);
62  }
63  DrawTextShadow(surface, 0, 20, text, surface->MakeColor(0xE0, 0xFF, 0xE0, 0xFF), surface->MakeColor(0x00, 0x00, 0x00, 0xFF), MDFN_FONT_9x18_18x18, 230);
64 }
65 
66 
SaveStatesActive(void)67 bool SaveStatesActive(void)
68 {
69  return(StateStatus);
70 }
71 
SSCleanup(void)72 static void SSCleanup(void)
73 {
74   if(PreviewSurface)
75   {
76    delete PreviewSurface;
77    PreviewSurface = NULL;
78   }
79 
80   if(TextSurface)
81   {
82    delete TextSurface;
83    TextSurface = NULL;
84   }
85 
86   if(StateStatus)
87   {
88    if(StateStatus->gfx)
89     delete[] StateStatus->gfx;
90 
91    delete StateStatus;
92    StateStatus = NULL;
93   }
94 }
95 
96 // TODO: Handle memory allocation errors.
DrawSaveStates(int32 screen_w,int32 screen_h,double exs,double eys,int rs,int gs,int bs,int as)97 void DrawSaveStates(int32 screen_w, int32 screen_h, double exs, double eys, int rs, int gs, int bs, int as)
98 {
99  if(StateShow <= Time::MonoMS())
100  {
101   SSCleanup();
102  }
103 
104  if(StateStatus)
105  {
106   if(!PreviewSurface)
107   {
108    PreviewSurface = new MDFN_Surface(NULL, StateStatus->w + 2, StateStatus->h + 2, StateStatus->w + 2, MDFN_PixelFormat(MDFN_COLORSPACE_RGB, rs, gs, bs, as));
109 
110    PreviewRect.x = PreviewRect.y = 0;
111    PreviewRect.w = StateStatus->w + 2;
112    PreviewRect.h = StateStatus->h + 2;
113 
114    MDFN_DrawFillRect(PreviewSurface, 0, 0, StateStatus->w + 2, StateStatus->h + 2, PreviewSurface->MakeColor(0x00, 0x00, 0x9F, 0xFF), PreviewSurface->MakeColor(0x00, 0x00, 0x00, 0x80));
115 
116    uint32 *psp = PreviewSurface->pixels;
117 
118    psp += PreviewSurface->pitchinpix;
119    psp++;
120 
121    if(StateStatus->gfx)
122    {
123     for(uint32 y = 0; y < StateStatus->h; y++)
124     {
125      uint8 *src_row = StateStatus->gfx + y * StateStatus->w * 3;
126 
127      for(uint32 x = 0; x < StateStatus->w; x++)
128      {
129       psp[x] = PreviewSurface->MakeColor(src_row[0], src_row[1], src_row[2], 0xFF);
130       src_row += 3;
131      }
132      psp += PreviewSurface->pitchinpix;
133     }
134    }
135 
136    if(!TextSurface)
137    {
138     TextSurface = new MDFN_Surface(NULL, 230, 40, 230, MDFN_PixelFormat(MDFN_COLORSPACE_RGB, rs, gs, bs, as));
139 
140     TextRect.x = TextRect.y = 0;
141     TextRect.w = 230;
142     TextRect.h = 40;
143    }
144 
145    if(IsMovie)
146    {
147     char text[256];
148 
149     if(StateStatus->current_movie > 0)
150      trio_snprintf(text, 256, _("-recording movie %d-"), StateStatus->current_movie-1);
151     else if (StateStatus->current_movie < 0)
152      trio_snprintf(text, 256, _("-playing movie %d-"),-1 - StateStatus->current_movie);
153     else
154      trio_snprintf(text, 256, _("-select movie-"));
155 
156     DrawStateMovieRow(TextSurface, StateStatus->status, StateStatus->current, StateStatus->recently_saved, text);
157    }
158    else
159     DrawStateMovieRow(TextSurface, StateStatus->status, StateStatus->current, StateStatus->recently_saved, _("-select state-"));
160   }
161  } // end if(StateStatus)
162 
163  if(PreviewSurface)
164  {
165   MDFN_Rect tdrect, drect;
166 
167   int meow = ((screen_w / CurGame->nominal_width) + 1) / 2;
168   if(!meow) meow = 1;
169 
170   tdrect.w = TextRect.w * meow;
171   tdrect.h = TextRect.h * meow;
172   tdrect.x = (screen_w - tdrect.w) / 2;
173   tdrect.y = screen_h - tdrect.h;
174 
175   BlitRaw(TextSurface, &TextRect, &tdrect);
176 
177   drect.w = PreviewRect.w * meow;
178   drect.h = PreviewRect.h * meow;
179   drect.x = (screen_w - drect.w) / 2;
180   drect.y = screen_h - drect.h - tdrect.h - 4;
181 
182   BlitRaw(PreviewSurface, &PreviewRect, &drect);
183 
184  }
185 
186 }
187 
MT_SetStateStatus(StateStatusStruct * status)188 void MT_SetStateStatus(StateStatusStruct *status)
189 {
190  SSCleanup();
191 
192  IsMovie = FALSE;
193  StateStatus = status;
194 
195  if(status)
196   StateShow = Time::MonoMS() + MDFN_GetSettingUI("osd.state_display_time");
197  else
198   StateShow = 0;
199 }
200 
MT_SetMovieStatus(StateStatusStruct * status)201 void MT_SetMovieStatus(StateStatusStruct *status)
202 {
203  SSCleanup();
204 
205  IsMovie = TRUE;
206  StateStatus = status;
207 
208  if(status)
209   StateShow = Time::MonoMS() + MDFN_GetSettingUI("osd.state_display_time");
210  else
211   StateShow = 0;
212 }
213 
214