MSX Village forum

La Place des Développeurs Projet Carwar

aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2699

Le 30/03/2011 à 16h54

Reprise du message précédent

Le but est de faire un jeu qui soit utilisable par le plus grand nombre de fans de MSX dans le monde.
Je sais bien qu'en passant à 60Hz la frame dure moins longtemps et que cela réduit donc les perfs/frame pour le CPU et le GPU. Mais si c'est la meilleure solution pour qu'un maximum de personnes puissent profiter du jeu, je trouverai une solution. ^^

En fait, ce qui n'est pas clair, c'est les relations entre la fréquence d'affichage native du MSX, la fréquence modifié en soft et la fréquence du moniteur. :hum


On est toujours ignorant avant de savoir.
Github    
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1487

Le 30/03/2011 à 17h21
aoineko :
En fait, ce qui n'est pas clair, c'est les relations entre la fréquence d'affichage native du MSX, la fréquence modifié en soft et la fréquence du moniteur


Il n'y a pas de fréquence native du MSX ...

La seule fréquence du MSX est celle déterminée par le VDP à travers le registre dédié.

Ensuite, soit le moniteur a une fréquence fixe, soit il s'adapte à celle qu'il reçoit par le signal vidéo.



Metalion :
PS : Je ne suis pas sur que le fait de basculer le VDP à 60Hz fait également basculer le mode de codification de l'image (NTSC ou PAL) qui est autrement plus complexe que la simple fréquence. Autrement dit, je me demande si sur les MSX européens, on ne fait en fait que basculer entre du PAL 50Hz et du PAL 60Hz ...


Après avoir fait quelques recherches dans la doc Yamaha sur le VDP 9938, je pense que je peux préciser la question du standard vidéo.



En fait, le VDP ne sort que des signaux RGB et une fréquence de synchronisation. Tout autre traitement vidéo est donc fait en dehors du VDP, sur la carte mère de l'ordinateur. Etant donné que les systèmes PAL et NTSC sont en fait des normes de modulation et de combinaison des signaux RGB d'origine, cela signifie donc que l'émission d'une image au standard PAL ou NTSC dépend de l'origine de l'ordinateur et non pas du VDP.



En clair, si l'image est transmise au moniteur/téléviseur à travers les signaux RGB, il n'y a aucun souci de standard.



En revanche, si l'image est transmise à travers une connexion composite (CVBS ou S-Vidéo), le signal sera envoyé selon le standard de la machine (PAL pour les MSX européens, NTSC pour les MSX japonais), quelle que soit la fréquence du VDP (50Hz ou 60Hz).



On peut donc générer uniquement du PAL 50Hz/60Hz sur les MSX européens, et du NTSC 50Hz/60Hz sur les MSX japonais.


MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2699

Le 30/03/2011 à 17h46
Metalion :
Il n'y a pas de fréquence native du MSX ...

La seule fréquence du MSX est celle déterminée par le VDP à travers le registre dédié.

Ensuite, soit le moniteur a une fréquence fixe, soit il s'adapte à celle qu'il reçoit par le signal vidéo.





Ce que j'appelle la fréquence native, c'est la valeur du registre VDP au démarrage (qui n'est pas la même sur un MSX japonais ou européen).



Faudra que je contact des fans de MSX japonais pour savoir comment ils se débrouillent avec les jeux 50Hz. :)



EDIT : Remarque, y a la solution de faire 2 versions (50/60) et/ou de laisser choisir dans les options du jeu. Edité par aoineko Le 30/03/2011 à 17h56


On est toujours ignorant avant de savoir.
Github    
GDX Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 17/01/2011 à 08h52

Messages: 3004

Le 30/03/2011 à 18h24
aoineko :
Faudra que je contact des fans de MSX japonais pour savoir comment ils se débrouillent avec les jeux 50Hz. :)


Pas la peine. Pratiquement personne n'en a tenu compte que ce soit au japon ou ailleurs malheureusement.



EDIT : En relisant, je me suis rendu compte que tu ne parlais pas de programmation mais d'utilisation. Les japonais avaient le même problème que nous sauf que là-bas, les TV multi-standard ont toujours été rares donc, il y avait moins de TV qui supportent le 50 Hz que de TV qui supportent le 60Hz en Europe. De nos jours, les TV numériques à écran plat ont pris le relais donc il serait interessant de savoir si elles supportent le 50 Hz en effet. Edité par GDX Le 01/04/2011 à 06h57
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2699

Le 01/04/2011 à 00h40
Bon, je crash dès que j'essaye de setter mon hook de VBLANK. :(

Si un pro du ASM peut se pencher sur la question, ça se passe ci-dessous. ^^

La fonction SetHook prend 2 paramètres : l'adresse du hook (ix 4-5) et l'adresse de la fonction vers laquelle sauté (ix 6-7).
Si la fonction est égal à 0, on set un ret.
Sinon, on set un jump vers la fonction.

Code ASM :
_SetHook:
pushix
ldix,#0
addix,sp
lda,6 (ix)
ora,7 (ix)
jrNZ,00102$
ldl,4 (ix)
ldh,5 (ix)
ld(hl),#0xC9
jr00104$
00102$:
ldl,4 (ix)
ldh,5 (ix)
ld(hl),#0xC3
inc4 (ix)
jrNZ,00107$
inc5 (ix)
00107$:
ldl,4 (ix)
ldh,5 (ix)
lda,6 (ix)
ld(hl),a
inchl
lda,7 (ix)
ld(hl),a
00104$:
popix
ret


Pour mes testes, je passe la fonction ci-dessous... qui ne fait qu'un return.

Code ASM :
_VBlankInterrupt:
 ret


Une idée ?


On est toujours ignorant avant de savoir.
Github    
GDX Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 17/01/2011 à 08h52

Messages: 3004

Le 01/04/2011 à 04h04
Peux-tu écrire ton programme en opcodes standard STP ?

http://www.gaby.de/z80/z80sean.txt

http://fms.komkon.org/MSX/Docs/Z80-1.txt

Pour que ton programme soit cadencé à peu près de la même façon en 50 Hz qu'en 60 Hz, tu peux faire un compteur et une condition afin de sauter ta routine 1 frame sur 5 en mode 60 Hz. Edité par GDX Le 01/04/2011 à 04h22
   
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1487

Le 01/04/2011 à 09h13
Le code généré par ton compilateur est vraiment très pénible :(
Non seulement il use et abuse de l'adressage indirect par IX ...
Ce qui pénalise fortement la vitesse d'éxécution est la lisibilité ...
Mais en plus il génère un code qui n'est pas conforme à la syntaxe standard du Z80 :( :(

Notamment, je suppose que l'instruction "ld a,5 (ix)" est en fait "ld a,(ix+5)" en syntaxe correcte ...

Sinon : pendant toute modification du hook, il faut bien évidemment arrêter toute interruption, donc :

Code :
di
...
(ton code)
..
ei


A part cela, je ne voit pas d'autre problème, mais il faut bien dire (même si je me répète) que ton code est obtus ...


MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
   
MSXosaure Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 777

Le 01/04/2011 à 09h23
Je suis plus pour la solution de GDX.
Dans le zip du crossassembler asmsx v.0.12 g, le modèle de MineSweeper donne un bon exemple de ce qui peut être fait pour la détection du type de MSX et de sa fréquence et la gestion pour un compteur mais on peut l'utiliser de bien d'autres façon (voir post précédent;))...

Code ASM :
 
;---------------------------------------------------------
; CONSTANTS
;---------------------------------------------------------
; VRAM addresses
        CHRTBL  equ     0000h
        NAMTBL  equ     1800h
        CLRTBL  equ     2000h
        SPRTBL  equ     3800h
        SPRATR  equ     1B00h
; BIOS routine - Turbo-R computers only!
        SETCPU  equ     0180h
; Constantes de la BIOS
        MSXID1  equ     002bh
        MSXID3  equ     002dh
; System variables addresses
        CLIKSW  equ     0f3DBh  ; Keyboard click sound
        FORCLR  equ     0f3e9h  ; Foreground colour
        RG9SAV  equ     0ffe8h  ; V9938 register copy
;----------------------------------------------------------
 
;
;
;
 
;----------------------------------------------------------
INITIALISATION:
; All previous initialization processes
;----------------------------------------------------------
; Sets R register to range 0-127
        xor     a
        ld      r,a
; Silent key click
        ld      [CLIKSW],a
; If Turbo-R is detected, switch to Z80 mode
        ld      a,[MSXID3]
        cp      3
        jr      nz,@@DONE
        ld      a,$80
        call    SETCPU
@@DONE:
; Determines screen frequency
        ld      b,60
        ld      a,[MSXID3]
        or      a
        jr      nz,@@MSX2
; First generation MSX
        ld      a,[MSXID1]
        rla
        jr      nz,@@OK
        ld      b,50
        jr      @@OK
; MSX2 or higher (V9938/V9958)
@@MSX2:
        ld      a,[RG9SAV]
        and     $02
        jr      z,@@OK
        ld      b,60
; Store frequency
@@OK:
        ld      a,b
        ld      [FREQUENCY],a
; Desactivate clock
        call    CLOCK_STOP
; Install interruption routine
        ld      hl,$fd9f
        ld      bc,INTERRUPTION
        ld      [hl],$c3
        inc     hl
        ld      [hl],c
        inc     hl
        ld      [hl],b
 
;
;
;
 
;----------------------------------------------------------
INTERRUPTION:
;----------------------------------------------------------
        push    af
        push    bc
        push    de
        push    hl
        call    CLOCK_UPDATE
        pop     hl
        pop     de
        pop     bc
        pop     af
        ret
;----------------------------------------------------------
 
;
;
;
;----------------------------------------------------------
CLOCK_UPDATE:
; Updates clock if necesary
;----------------------------------------------------------
; Test if clock is on
        ld      a,[CLOCK]
        or      a
        ret     z
; Adjust frame counter
        ld      hl,COUNTER
        inc     [hl]
; If equal to frequency, update clock
        ld      a,[FREQUENCY]
        cp      [hl]
        ret     nz
; Init frame counter to zero
        xor     a
        ld      [hl],a
; Increase seconds
        ld      a,[SECONDS]
        add     01h
        daa
        ld      [SECONDS],a
        cp      60h
        jr      nz,@@UPDATE
; Increase minutes
        xor     a
        ld      [SECONDS],a
        ld      a,[MINUTES]
        add     01h
        daa
        ld      [MINUTES],a
@@UPDATE:
; Convert BCD variables to ASCII text
        ld      a,[SECONDS]
        call    BCD_TO_ASCII
        ld      hl,TIMER+4
        ld      [hl],e
        dec     hl
        ld      [hl],d
        ld      a,[MINUTES]
        call    BCD_TO_ASCII
        ld      hl,TIMER+1
        ld      [hl],e
        dec     hl
        ld      [hl],d
; Print text
        ld      hl,TIMER
        ld      de,NAMTBL+25
        ld      bc,5
        call    LDIRVM
        ret
;----------------------------------------------------------
 



Le MSXien le plus à l'ouest :fou ... ou presque :D
osaurer
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2699

Le 01/04/2011 à 17h16
Si j'avais fait le jeu en assembleur, j'en serai encore à essayer de faire bouger mes sprites. ^^
Et puis, l'avantage du C++, c'est qu'on peut mixer avec du code ASM pour les parties les plus importantes.

Pour en revenir a mon programme, je vais essayer de setter le hook en dur en ASM avec les adresses du hook et de la fonction directement dans le code ; je verrai bien si le problème viens de ma fonction qui set le hook ou bien du hook en lui même (même si, étant vide, je vois pas comment il pourrait poser problème ^^).

Pour la fréquence, elle est setté en dur à 60Hz via le code ; je vais laisser comme ça.


On est toujours ignorant avant de savoir.
Github    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2699

Le 04/04/2011 à 00h56
Mon compteur de seconde par interruption VBlank fonctionne ; par contre il lag un peu.
Je me demandais ; que ce passe t'il si un VBlank interviens alors qu'une instruction di est en cours ?
Il attend un ei ou l'interruption est perdu ?
S'il est perdu, ça expliquerai peut être le lag. :hum Edité par aoineko Le 04/04/2011 à 01h05


On est toujours ignorant avant de savoir.
Github    
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1487

Le 04/04/2011 à 11h56
Dans le cas où une IRQ arrive sur le bus du Z80, si l'opération DI a été exécutée, l'interruption est perdue.
D'où l'intérêt de limiter les phases DI/EI au strict minimum (voire même à anticiper l'EI d'une instruction).

Ceci dit, sauf si ton code est truffé de phases DI/EI, tu ne devrais pas voir de modification sur ton compteur. J'ai un jeu en développement, qui contient des phases DI/EI normales (pour les accès VDP et VRAM), et qui utilise un compteur en secondes basé sur l'utilisation du hook en $FD9F, et je ne vois aucune perturbation visible ...


MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2699

Le 13/04/2011 à 23h20
J'ai implémenté une nouvelle compression sur mes sprites qui m'a fait gagné 5 Ko !!
De toute façon, j'avais plus le choix, sinon il y avait plus la place sur ma cartouche 32Ko pour mettre le code pour finir le jeu. ^^

Pour ceux que ça intéresse, la compression s'appuie sur l'élimination des 0 (transparence) qui pullulent dans les sprites.
En Y, je calculs la première et dernière ligne contenant un point non transparent et je stock l'info sur 1 octet sous la forme [offset Y|taille Y].
Par exemple, si un sprite 13x11 de voiture à l'horizontal commence et fini par 3 ligne complétement transparentes. Je commence donc par un octet = [3|5].
Ensuite, je fais de même avec X pour chaque ligne. Elle commence donc toujours par un octet du type [offset X|taille X] suivi des données comprises entre ces bornes.

Avec cette compression, mon premier sprite passe de 143 octets (13x11) à 77 octets ; soit 50% de compression. :D

J'ai encore une solution de compression en créant une palette de 16 couleurs par sprite et en codant chaque point sur 4 bits... mais bon, pour l'instant, je vais me contenter de mes 5 Ko gagné.


On est toujours ignorant avant de savoir.
Github    
GuillianSeed Membre non connecté

Villageois

Rang

Avatar

Groupe : compte ++

Inscrit le : 16/10/2009 à 18h53

Messages: 683

Le 13/04/2011 à 23h42
Bravo !!
Il n'y a pas que dans la rénovation que le système D compte beaucoup !!
Bonne continuation Aoineko ! Et j'espère voir Carwar dans le MSXDev !!!!!!
:top :top :top


MSX1 Sony HB501F / MSX2+ FSA1FX / MSX2+ FSA1WX / MSX2+ FSA1WSX / MSX Turbo-R ST / MSX Turbo-R GT
Moonsound 2.0 & DalSoRi - Interface CF & CF Card Interface - MegaFlash SCC 512Ko & 2x512ko - SRam 512Ko - Megaflashrom SCC + SD
MSX4Ever !!
Franck Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 22h54

Messages: 3295

Le 14/04/2011 à 10h11
MSXDev ça va être dur, il faut que le jeu tourne sur un MSX1 ^^
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2699

Le 14/04/2011 à 10h43
Je pense le présenter au MSXDev en hors catégorie.
Si ça peut leur donner envi de faire dans le future un concourt MSX2 en plus de celui pour MSX1, ça serait cool. :)


On est toujours ignorant avant de savoir.
Github    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2699

Le 05/05/2011 à 00h52
Après le chargement d'un fichier depuis la disquette, le jeu se met dans une boucle infini.
J'ai essayé de tracer le code ASM, mais je vois pas ce qui se passe.
Mes variables en RAM ne semble pas écrasé par le BLTVD (file2vram copy), mais le flow ne reprend pas normalement.
Au cas ou qq'un peut y jeter œil, voici le code :
carwar_prb_infiniteLoop.zip


On est toujours ignorant avant de savoir.
Github    
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie