Main Page | Data Structures | Directories | File List | Data Fields | Globals

display.hcc

Go to the documentation of this file.
00001 
00019 /*
00020  * Set the Clock rate for this domain. 25.175 Mhz is required for the Video output.
00021  */
00022 #define PAL_TARGET_CLOCK_RATE 25175000
00023 
00024 /******** System Includes *************/
00025 #include <stdlib.hch>
00026 
00027 #include "pal_master.hch"
00028 
00029 /******** Application Includes ********/
00030 #include "configuration.hch"
00031 #include "audio.hch"
00032 #include "eventhandler_shared.hch"
00033 #include "mouse_shared.hch"
00034 #include "smartmedia_shared.hch"
00035 #include "display_shared.hch"
00036 #include "display.hch"
00037 
00038 #if HAVE_DEBUG
00039         #include "debug.hch"
00040 #endif
00041 
00042 
00043 
00044 /*
00045  * Channel to notify others when new mousedata is available. If so
00046  * Then mousedata struct is updated with shared data.
00047  */
00048 chan unsigned 1 maskupdate_notification;
00049 
00050 
00051 
00065 void display_main(skindata_t *skindata, audiodata_t *audiodata, events_t *events, mousedata_t *mousedata) {
00066         /*
00067          * Setup macro's RAM/Video handles and to coordinate pixel writing.
00068          */
00069         macro expr CLOCKRATE = PAL_ACTUAL_CLOCK_RATE;
00070         macro expr VIDEOOUT = PalVideoOutOptimalCT(CLOCKRATE);
00071         macro expr RAM_BANK0 = PalPL2RAMCT(0);
00072         macro expr DW = PalPL2RAMGetMaxDataWidthCT();
00073         macro expr AW = PalPL2RAMGetMaxAddressWidthCT();
00074         macro expr VISIBLEX = PalVideoOutGetVisibleX(VIDEOOUT, CLOCKRATE);
00075         macro expr TOTALX = PalVideoOutGetTotalX(VIDEOOUT, CLOCKRATE);
00076         macro expr TOTALY = PalVideoOutGetTotalY(VIDEOOUT);
00077         macro expr SCANX = PalVideoOutGetX(VIDEOOUT);
00078         macro expr SCANY = PalVideoOutGetY(VIDEOOUT);
00079         
00080         unsigned DW pixeldata;
00081         unsigned 24 visual_graph_color;
00082         unsigned AW address, address_offset;
00083 
00084 
00085 
00086         /*
00087          * If the passed button_state tells us the button is active, then we
00088          * the button is 'on' and we draw it inverted. Otherwise we draw the
00089          * area of the button normally.
00090          */
00091         macro proc draw_button(button_state) {
00092                 if (button_state == pixeldata[31:24]) {
00093                         PalVideoOutWrite(VIDEOOUT, ~PIXEL);
00094                 } else {
00095                         PalVideoOutWrite(VIDEOOUT, PIXEL);
00096                 }
00097         }
00098 
00099         /*
00100          * Prime Rendering Pipeline to start where the skin starts.
00101          */
00102         PalPL2RAMSetReadAddress(RAM_BANK0, ADDRESS_SKIN_START);
00103 
00104         /*
00105          * Run the following tasks indefinatly and in parallel
00106          */
00107         while (TRUE) {
00108                 par {
00109                         /*
00110                          * Before starting this loop we allready set the the
00111                          * address. Therefor we can start reading the
00112                          * previously set address and prepare the next address
00113                          * for the next cycle.
00114                          */
00115                         PalPL2RAMRead(RAM_BANK0, &pixeldata);
00116                         PalPL2RAMSetReadAddress(RAM_BANK0, address_offset +address);
00117 
00118                         /*
00119                          */
00120                         switch (events->mode) {
00121                                 case MODE_HELP:
00122                                         address_offset = ADDRESS_HELP_START;
00123                                         break;
00124                                 case MODE_GRAPH:
00125                                         address_offset = ADDRESS_GRAPHMASK_START;
00126                                         break;
00127                                 default:
00128                                         address_offset = ADDRESS_SKIN_START;
00129                                         break;
00130                         }
00131 
00132                         if (MODE_GRAPH == events->mode) {
00133                                 par {
00134                                         visual_graph_color = ((unsigned 8)(0 @ audiodata->fft_info.read[pixeldata[31:24]]) << 1) @ ((unsigned 8)(0 @ audiodata->fft_info.read[pixeldata[31:24]]) << -1) @ ((unsigned 8)(0 @ audiodata->fft_info.read[pixeldata[31:24]]) << 0);
00135                                         PalVideoOutWrite(VIDEOOUT, 0 @ visual_graph_color);
00136                                 }
00137                         } else {
00138                                 /*
00139                                  * Determin what to draw where here. Every case has an
00140                                  * if else statement comparing wether to draw something
00141                                  * special or the background. Every specific drawing
00142                                  * obviously only happens in the masked area.
00143                                  */
00144                                 switch (pixeldata[31:24]) {
00145                                         /*
00146                                          */
00147                                         case AREA_WAVEFORM:
00148                                                 if (SCANY == 0 @ skindata->area_waveform_bottom -(0 @ (audiodata->ifft_info.read[((SCANX -(0 @ skindata->area_waveform_left)) <-8)]))) {
00149                                                         PalVideoOutWrite(VIDEOOUT, skindata->color_area_waveform);
00150                                                 } else {
00151                                                         PalVideoOutWrite(VIDEOOUT, PIXEL);
00152                                                 }
00153                                                 break;
00154 
00155                                         /*
00156                                          * Volume control over the Y-axis.
00157                                          */
00158                                         case AREA_VOLUME_YAXIS:
00159                                                 /*
00160                                                  * The volume_position stores the
00161                                                  * highest point of our bar. Every
00162                                                  * pixel after this point is drawn.
00163                                                  */
00164                                                 if (SCANY >= 0 @ events->volume_position) {
00165                                                         PalVideoOutWrite(VIDEOOUT, skindata->color_area_volume);
00166                                                 } else {
00167                                                         PalVideoOutWrite(VIDEOOUT, PIXEL);
00168                                                 }
00169                                                 break;
00170                         
00171                                         /*
00172                                          * Spectrum Analyzer
00173                                          */
00174                                         case AREA_SPECTRUM_ANALYZER:
00175                                                 /*
00176                                                  * We draw every pixel that is smaller TODO
00177                                                  */
00178                                                 if ((SCANY >= (0 @ skindata->area_spectrum_bottom) -(0 @ audiodata->fft_info.read[(SCANX -(0 @ skindata->area_spectrum_left))[9:2]])) && ((SCANX -(0 @ skindata->area_spectrum_left)) <- 2)) {
00179                                                         PalVideoOutWrite(VIDEOOUT, PIXEL_SPECTRUM);
00180                                                 } else {
00181                                                         PalVideoOutWrite(VIDEOOUT, PIXEL);
00182                                                 }
00183                                                 break;
00184 
00185                                         /*
00186                                          * Since all buttons are drawn equally, either
00187                                          * we draw them normally or we inverse them, we
00188                                          * can handle them almost equally.
00189                                          */
00190                                         case BUTTON_PRESET_1:   /* fall through */
00191                                         case BUTTON_PRESET_2:   /* fall through */
00192                                         case BUTTON_PRESET_3:   /* fall through */
00193                                         case BUTTON_PRESET_4:   /* fall through */
00194                                         case BUTTON_PRESET_5:   /* fall through */
00195                                         case BUTTON_PRESET_6:
00196                                                 /*
00197                                                  * The active preset tells us what
00198                                                  * button is currently enabled. We must
00199                                                  * however not forget to add the preset
00200                                                  * button offset to possibly match it
00201                                                  * with the current mask.
00202                                                  */
00203                                                 draw_button((events->active_preset +BUTTON_PRESET_1) <- 8);
00204                                                 break;
00205 
00206                                         case BUTTON_PRECISE:            /* fall through */
00207                                         case BUTTON_CONCAVE_HALF:       /* fall through */
00208                                         case BUTTON_CONVEX_HALF:        /* fall through */
00209                                         case BUTTON_CONCAVE_FULL:       /* fall through */
00210                                         case BUTTON_CONVEX_FULL: 
00211                                                 /*
00212                                                  * equalizer mode tells us what button
00213                                                  * is currently enabled. By adding the
00214                                                  * equalizer mode button offset we can
00215                                                  * safley check wether it matches our
00216                                                  * mask.
00217                                                  */
00218                                                 draw_button((0 @ events->equalizer_mode) +BUTTON_PRECISE);
00219                                                 break;
00220 
00221                                         case BUTTON_LOG:
00222                                                 /*
00223                                                  * 
00224                                                  */
00225                                                 draw_button((0 @ audiodata->display_log) +BUTTON_LOG);
00226                                                 break;
00227 
00228                                         /*
00229                                          * The default case is split up into two parts
00230                                          * actually. This is because we have 128 bands
00231                                          * for the equalizer and thus as many mask
00232                                          * entries. Since we don't want 128 identical
00233                                          * cases we check wether the equalizer mask is
00234                                          * currently active and if so draw it. If this
00235                                          * is not the case we simply draw the
00236                                          * background.
00237                                          */
00238                                         default:
00239                                         /* (pixeldata[31:24] <= AREA_EQUALIZER_MAX) &&  */
00240                                                 if ((AREA_EQUALIZER_MIN <= pixeldata[31:24]) && (!events->locked_display)) {
00241                                                         if ((SCANY == 0 @ events->equalizer_display[(pixeldata[31:24] -AREA_EQUALIZER_MIN) <- 7]) || ((SCANY +1) == 0 @ events->equalizer_display[(pixeldata[31:24] -AREA_EQUALIZER_MIN) <- 7])) {
00242                                                                 PalVideoOutWrite(VIDEOOUT, skindata->color_equalizer);
00243                                                         } else {
00244                                                                 PalVideoOutWrite(VIDEOOUT, PIXEL);
00245                                                         }
00246                                                 } else {
00247                                                         PalVideoOutWrite(VIDEOOUT, PIXEL);
00248                                                 }
00249                                         break;
00250                                 }
00251                         }
00252 
00253                         /*
00254                          * We compare our current X and Y scan positions of the
00255                          * output to the x and y data of the mouse. When those
00256                          * are equal we set the current mask to the mask stored
00257                          * in memory at that location. We then know what mask
00258                          * is to be used for events.
00259                          */
00260                         if (MOUSE_UPDATED == mousedata->status) {
00261                                 if ((SCANX == 0 @ mousedata->x) && (SCANY == 0 @ mousedata->y)) {
00262                                         par {
00263                                                 events->mask = pixeldata[31:24];
00264                                                 mousedata->status = MOUSE_NOT_UPDATED;
00265                                                 maskupdate_notification ! MOUSE_UPDATED;
00266                                         }
00267                                 } else {
00268                                         delay;
00269                                 }
00270                         } else {
00271                                 delay;
00272                         }
00273 
00274                         /*
00275                          * The current position of the screen can lay in an
00276                          * area called the blanking area. We don't have data
00277                          * for this area as it is not drawn. We therefor have
00278                          * to determin wether we are beyond the visible area of
00279                          * the screen, but before the end of the total width of
00280                          * the screen. Our pipeline consists of 5 total stages.
00281                          * Therefor we have to substract 5 pixels.
00282                          */
00283                         if ((SCANX > (VISIBLEX - 5)) && (SCANX <= (TOTALX - 5))) {
00284                                 /*
00285                                  * We are in the blanking area of the screen.
00286                                  * If we are on the last line, and thus last
00287                                  * pixel we reset our address counter.
00288                                  */
00289                                 if (SCANY == (TOTALY -1)) {
00290                                         /*
00291                                          * Reset our draw address counter to 0.
00292                                          */
00293                                         address = 0;
00294                                 } else {
00295                                         /*
00296                                          * We have reached the end of the
00297                                          * visible line, but not the end of
00298                                          * the screen. Therefore do nothing.
00299                                          */
00300                                         delay;
00301                                 }
00302                         } else {
00303                                 /*
00304                                  * Increase the memory counter for each pixel
00305                                  * drawn thus keeping the memory location in
00306                                  * sync with the current pixel position.
00307                                  */
00308                                 address++;
00309                         }
00310                 }
00311         }
00312 } /* --- display_main() --- */
00313 
00314 
00315 
00328 void reload_equalizer(events_t *events, unsigned 4 *equalizer_levels) {
00329         unsigned 7 equalizer_band;
00330 
00331         events->locked_display = TRUE;
00332         delay;
00333         do {
00334                 events->equalizer_display[equalizer_band] = equalizer_table_inv[equalizer_levels[equalizer_band]];
00335                 equalizer_band++;
00336         } while (equalizer_band);
00337         events->locked_display = FALSE;
00338 } /* --- reload_equalizer() --- */

Generated on Thu Dec 9 14:37:06 2004 for Graphic Equalizer 2 by  doxygen 1.3.9.1